图层时间
CAMediaTiming协议
-
CAMediaTiming
协议定义了在一段动画内用来控制逝去时间的属性的集合,CALayer
和CAAnimation
都实现了这个协议。 -
持续和重复
duration
和repeatCount
默认都是0。但这不意味着动画时长为0秒,或者0次,这里的0仅仅代表了“默认”,也就是0.25秒和1次。
创建重复动画的另一种方式是使用repeatDuration
属性,它让动画重复一个指定的时间,而不是指定次数。还可以设置一个叫做autoreverses
的属性(BOOL类型),可以在动画结束后执行逆动画。
-
相对时间
beginTime
指定了动画开始之前的的延迟时间。这里的延迟从动画添加到可见图层的那一刻开始测量,默认是0(就是说动画会立刻执行)。
speed
是一个时间的倍数,默认1.0,减少它会减慢图层/动画的时间,增加它会加快速度。如果2.0的速度,那么对于一个duration
为1的动画,实际上在0.5秒的时候就已经完成了。
timeOffset
和beginTime
类似,但是和增加beginTime
导致的延迟动画不同,增加timeOffset
只是让动画快进到某一点,例如,对于一个持续1秒的动画来说,设置timeOffset
为0.5意味着动画将从一半的地方开始。
-
fillMode
设置fillMode
时需要把removeOnCompletion
设置为NO
。
层级关系时间
- 对
CALayer
或者CAGroupAnimation
调整duration
和repeatCount
/repeatDuration
属性并不会影响到子动画。但是beginTime
,timeOffset
和speed
属性将会影响到子动画。 -
全局时间和本地时间
- CoreAnimation有一个全局时间的概念,也就是所谓的马赫时间。马赫时间在设备上所有进程都是全局的,但是在不同设备上并不是全局的。可以使用
CACurrentMediaTime
函数来访问马赫时间:
CFTimeInterval time = CACurrentMediaTime()
这个函数返回的值其实无关紧要(它返回了设备自从上次启动后的秒数,并不是你所关心的),它真实的作用在于对动画的时间测量提供了一个相对值。 - 每个
CALayer
和CAAnimation
实例都有自己本地时间的概念,是根据父图层/动画层级关系中的beginTime
,timeOffset
和speed
属性计算。就和转换不同图层之间坐标关系一样,CALayer同样也提供了方法来转换不同图层之间的本地时间。如下:
- (CFTimeInterval)convertTime:(CFTimeInterval)t fromLayer:(CALayer *)l
- (CFTimeInterval)convertTime:(CFTimeInterval)t toLayer:(CALayer *)l
手动动画
-
timeOffset
一个很有用的功能在于你可以它可以让你手动控制动画进程,通过设置speed
为0,可以禁用动画的自动播放,然后来使用timeOffset
来来回显示动画序列。这可以使得运用手势来手动控制动画变得很简单。
缓冲
动画速度
- 改变动画速度首先需要设置
CAAnimation
的timingFunction
属性,是CAMediaTimingFunction
类的一个对象。如果想改变隐式动画的计时函数,同样也可以使用CATransaction
的+setAnimationTimingFunction:
方法。有一些方式来创建CAMediaTimingFunction
,最简单的方式是调用+timingFunctionWithName:
的构造方法。这里传入如下几个常量之一:
kCAMediaTimingFunctionLinear
kCAMediaTimingFunctionEaseIn
kCAMediaTimingFunctionEaseOut
kCAMediaTimingFunctionEaseInEaseOut
kCAMediaTimingFunctionDefault
kCAMediaTimingFunctionLinear
创建了一个线性的计时函数,同样也是CAAnimation
的timingFunction
属性为空时候的默认函数。
kCAMediaTimingFunctionEaseIn
常量创建了一个慢慢加速然后突然停止的方法。
kCAMediaTimingFunctionEaseOut
则恰恰相反,它以一个全速开始,然后慢慢减速停止。
kCAMediaTimingFunctionEaseInEaseOut
创建了一个慢慢加速然后再慢慢减速的过程。
最后还有一个kCAMediaTimingFunctionDefault
,它和kCAMediaTimingFunctionEaseInEaseOut
很类似,但是加速和减速的过程都稍微有些慢。虽然它的名字说是默认的,但还是要记住当创建显式的CAAnimation
它并不是默认选项(换句话说,默认的图层行为动画用kCAMediaTimingFunctionDefault
作为它们的计时方法)。 -
缓冲和关键帧动画
CAKeyframeAnimation
有一个NSArray
类型的timingFunctions
属性,我们可以用它来对每次动画的步骤指定不同的计时函数。但是指定函数的个数一定要等于values
数组的元素个数减一,因为它是描述每一帧之间动画速度的函数。
let animation = CAKeyframeAnimation()
animation.keyPath = "backgroundColor"
animation.values = [UIColor.redColor().CGColor,UIColor.greenColor().CGColor,UIColor.blueColor().CGColor,UIColor.redColor().CGColor]
animation.duration = 4.0
let fn = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
animation.timingFunctions = [fn,fn,fn]
self.colorLayer.addAnimation(animation, forKey: nil)