动画是当今用户界面的关键因素。当使用核心动画的时候,动画是自动完成的。没有动画的循环和计数器。你的应用程序不负负责重绘,也不负责跟踪动画的当前状态。动画在独立线程里面自动执行,没有和你的应用程序交互。
本章提供了对动画类的概览,和介绍如何创建隐式的和显式的动画。
核心动画提供了一套你可以在你应用程序里面使用的动画类的表现:
除了要指定显示的动画类型,你还必须指定动画的间隔、它的速度(它的插值如何分布在整个动画过程)、动画循环时候的循环次数、动画周期完成的时候是否自动的反转、还有动画结束的时候它的可视化状态。动画类和CAMediaTiming协议提供所有这些功能甚至更多的功能。
CAAnimation、它的子类、时序协议被核心动画和Cocoa Animation Proxy功能共享。这些类将会在“动画类型和时序编程指南(Animation Types and Timing Programming Guide)”里面详细介绍。
核心动画的隐式动画模型假定所有动画图层属性的变化应该是渐进的和异步的。动态的动画场景可以在没有显式的动画图层时候实现。改变可动画显示的图层的属性将会导致图层隐式把图层从旧的值动画显示为新的值。虽然动画是持续的,但是设置新的目标值时会导致图层从当前状态动画过渡到新的目标值。
代码1显示了如果简单的触发一个隐式的动画,把图层从当前位置动画改变到新的位置。
代码 1 隐式的动画改变图层的position属性
1 2 | //假设layer当前position为(100.0,100.0) theLayer.position= CGPointMake (500 .0 ,500 .0 ); |
你可以隐式的一次动画改变图层的一个或者多个属性。你还可以隐式的同时动画改变多个图层。代码2的代码实现了4个同时触发的隐式动画。
代码 2 隐式的同时动画改变多个图层的多个属性
1 2 3 4 5 6 7 | // 在移动至远处时将Layer的opacity属性渐进至0 theLayer.opacity =0 .0 ; theLayer.zPosition= -100 ; //在移动至近处时将Layer的opacity属性渐进至1 anotherLayer.opacity =1 .0 ; anotherLayer.zPosition =100 .0 ; |
隐式动画使用动画属性中默认指定的动画时间,除非该时间已经被隐式或者显式的修改过。阅读“重载覆盖隐式动画时间”获取更多详情。
核心动画同时提供了一个显式的动画模型。该显式动画模型需要你创建一个动画对象,并设置开始和结束的值。显式动画不会开始执行,直到你把该动画应用到某个图层上面。代码3中的代码片段创建了一个显式动画,它实现一个层的不透明度从完全不透明过渡到完全透明的,3秒后返回重新执行。动画没有开始,直到它被添加到某一图层层。
代码 3 显式动画
1 2 3 4 5 6 7 8 9 | CABasicAnimation *theAnimation; theAnimation=[CABasicAnimation animationWithKeyPath : @ "opacity" ]; theAnimation.duration =3 .0 ; theAnimation.repeatCount =2 ; theAnimation.autoreverses= YES ; theAnimation.fromValue=[ NSNumber numberWithFloat :1 .0 ]; theAnimation.toValue=[ NSNumber numberWithFloat :0 .0 ]; [theLayer addAnimation :theAnimation forKey : @ "animateOpacity" ]; |
显式动画对于创建连续执行的动画非常有帮助。代码4显示了如何创建一个显式动画,把一个CoreImage滤镜应用到图层上面,动画显示其强度。这将导致“选择的图层”跳动,吸引用户的注意力。
代码 4 连续显式动画示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // The selection layer will pulse continuously. // This is accomplished by setting a bloom filter(梦维:用5.0和5.1模拟器测试发现CIBloom这个名称无法初始化滤镜,返回值为nil) on the layer // create the filter and set its default values CIFilter *filter = [CIFilter filterWithName : @ "CIBloom" ]; [filter setDefaults ]; [filter setValue :[ NSNumber numberWithFloat :5 .0 ] forKey : @ "inputRadius" ]; // name the filter so we can use the keypath to animate the inputIntensity // attribute of the filter [filter setName : @ "pulseFilter" ]; // set the filter to the selection layer's filters [selectionLayer setFilters :[ NSArray arrayWithObject :filter]]; // create the animation that will handle the pulsing. CABasicAnimation* pulseAnimation = [CABasicAnimation animation ]; // the attribute we want to animate is the inputIntensity // of the pulseFilter pulseAnimation.keyPath = @ "filters.pulseFilter.inputIntensity" ; // we want it to animate from the value 0 to 1 pulseAnimation.fromValue = [ NSNumber numberWithFloat : 0 .0 ]; pulseAnimation.toValue = [ NSNumber numberWithFloat : 1 .5 ]; // over a one second duration, and run an infinite // number of times pulseAnimation.duration = 1 .0 ; pulseAnimation.repeatCount = HUGE_VALF; // we want it to fade on, and fade off, so it needs to // automatically autoreverse.. this causes the intensity // input to go from 0 to 1 to 0 pulseAnimation.autoreverses = YES ; // use a timing curve of easy in, easy out.. pulseAnimation.timingFunction = [CAMediaTimingFunction functionWithName : kCAMediaTimingFunctionEaseInEaseOut ]; // add the animation to the selection layer. This causes // it to begin animating. We'll use pulseAnimation as the // animation key name [selectionLayer addAnimation :pulseAnimation forKey : @ "pulseAnimation" ]; |
你可以发送addAnimation:forKey:消息给目标图层来开始一个显式动画,把动画和标识符作为参数。一旦把动画添加到目标图层,动画将会一直执行直到动画完成,或者动画被从图层上面移除。把动画添加到图层时添加的标识符,同样也可以在停止动画的时候使用,通过调用removeAnimationForKey:。你可以通过给图层发送一个removeAllAnimations消息来停止图层所有的动画。
联系客服