高级动画技巧

高级动画技巧

有很多方式配置基于属性或关键帧的动画,应用程序需要同时或顺序执行动画,可以使用更高级的行为去同步时间或将动画链接起来。你也可以使用其它类型动画对象创建视觉过渡和其它有趣动画

过渡动画支持图层视觉变化

图层使用过渡动画,使用一个过渡对象让一个图层显示,另一个图层消失,不像基于属性的动画,是改变图层的一个属性,而过渡动画是操作图层的缓存图像来创建视觉效果,所以那很难或者
不可能只是单独的改变属性。标准类型的过渡动画可以执行显示、推入、移动或淡入淡出动画。

要执行过渡动画,需要创建一个 CATransition 对象加入到要动画的图层中。使用动画对象指定过渡的类型,设置起始和结束点。

// 两个view相同的位置,开始时 view1 可见,view2 不可见
CATransition *transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.duration = 1.0;
// Add the transition animation to both layers
[self.myView1.layer addAnimation:transition forKey:@"transition"];
[self.myView2.layer addAnimation:transition forKey:@"transition"];
// Finally, change the visibility of the layers
self.myView1.hidden = YES;
self.myView2.hidden = NO;

自定义动画时间

时间是动画的一个重要组成,CoreAnimation 通过方法和 CAMediaTiming属性协议来指定时间信息。CAAnimation和CALayer都采用了前面的协议。
当考虑到时间和动画时,理解图层对象如何随时间工作是很重要的。每个图层有有自己本地时间用来管理动画时间。通常不同的两个图层的本地时间很近,可以指定相同的时间值,用户不会感知到。但是图层的本地时间可以被父图层修改或自己的时间参数。如改变 speed属性。
CALayer类定义了两个方法 convertTime:fromLayer: convertTime:toLayer:,可以将一个固定的时间值转为图层本地时间,或将时间值从一个图层转换到另一个图层

// Getting a layer's current local time
// CACurrentMediaTime 函数是返回当前电脑当前时钟时间的快捷方法
CFTimeInterval localLayerTime = [myLayer convertTime: CACurrentMediaTime() fromLayer: nil];

可以使用 beginTime属性设置动画开始时间,有时连接两个动画时可以将后者的开始时间设置为前者的结束时间,如果想延迟动画开始时间,可能还要设置 fillMode = kCAFillModeBackwards,此种模式会让图层展示动画的开始值,即使图层对象在图层树中包含不同的值,如果没这种模式,将会产生一个跳跃,其它模式也可用。

使用 timeOffset属性在动画组中

暂停和恢复动画

暂停动画,可以利用图层采用的 CAMediaTiming协议,设置图层动画的速度为0.0,恢复时设置速度为非0即可

// Pausing and resuming a layer's animations
- (void)pauseLayer: (CALayer *)layer {
    CFTimeInterval pausedTime = [layer convertTime: CACurrentMediaTime() fromLayer: nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}
- (void)resumeLayer: (CALayer *)layer {
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [layer convertTime: CACurrentMediaTime() fromLayer: nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

显示事务改变动画参数

// creating an explicit transaction 
[CATransaction begin]; // 创建一个事务
theLayer.zPosition = 200.0;
theLayer.opacity = 0.0;
[CATransaction commit]; // 结束一个事务

创建显示事务的一个主要原因可以改变动画间隔、时间函数、其它参数。改变动画参数需要使用 setValue:forKye:方法在事务内修改相关的 key。

// change the default duration of animations
[CATransaction begin]; // 创建一个事务
[CATransaction setValue: [NSNumber numberWithFloat:10.0f] forKey: kCATransactionAnimationDuration];
[CATransaction commit]; // 结束一个事务
// 嵌套显示事务
[CATransaction begin]; // Outer transaction
// Change the animation duration to two seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
                forKey:kCATransactionAnimationDuration];
// Move the layer to a new position
theLayer.position = CGPointMake(0.0,0.0);
 
[CATransaction begin]; // Inner transaction
// Change the animation duration to five seconds
[CATransaction setValue:[NSNumber numberWithFloat:5.0f]
                 forKey:kCATransactionAnimationDuration];
// Change the zPosition and opacity
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit]; // Inner transaction
[CATransaction commit]; // Outer transaction

动画添加透视

// 为父图层创建一个简单的透视变换
// 变量 eyePosition表示从哪个方向观看,值越大越平坦,越小视觉差异越明显
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/eyePosition;
// Apply the transform to a parent layer.
myParentLayer.sublayerTransform = perspective;
[CATransaction begin];
long z = random() % 100;
sublayer.zPosition = 0.5;
NSLog(@"z = %zd", z);
[CATransaction commit];

猜你喜欢

转载自www.cnblogs.com/tzsh1007/p/12309537.html