今天在看Core Animation Guide中Pausing and Resuming Animation,对CALayer的时间系统理解不够。
通过demo以及查看API文档,目前理解如下。
1. 通过CAMediaTiming 协议中的属性和方法来精确的控制动画的时间信息,Core Animation 系统中,CAAnimation 和CALayer 均遵守该协议,
-系统通过CALayer 来配置implict动画的时间特征(即CAMediaTiming中的属性和方法)
- 开发者可配置CAAnimation实例的时间特征
2. 每个layer都有自己的时间,并且根据自己的时间来管理动画,一般情况下(比如,未设置CAMediaTiming中的属性和方法),layer的时间都相同
3. 每个layer的时间均受superlayer的时间影响
4. 可通过convertTime:fromLayer: 和convertTime:toLayer: 来转换时间
5. CAMediaTiming的主要方法/属性
- beginTime
- speed:时间流逝的速度,相对于superlayer而言,比如如果是2,则时间比super快一倍
-timeOffset:相对于super,自己时间的提前量,
以上三个属性通过以下公式更好理解(tp 为super的时间,t为layer自己的时间):
t=(tp - begin)* speed+timeOffSet
6.个人理解:当一个 CAAnimation加到CALayer时,比如 [layer addAnimation:animation forKey:@"animationKey"];
Core Animation 将基于目前的时间,计算在动画的各个时间点,layer的属性(比如position)。
动画时,到某个时间,layer属性将相应改变。
假如,对position进行动画,持续时间为10秒,position从(0,0)线性变化到(100,100),
将该动画加到layer时,Core Animation做相应计算,假设目前时间点(layer的时间)是100,那么时间为101时position为(10,10),时间到105时,position为(50,50)。
那么layer的时间是怎么计算呢,到底105在多久后到呢,CA就需要以上的公式计算。
如果layer的速度为2,beginTime 和timeOffsetJ均为0,可以看到,当superlayer的时间流过1秒,layer的时间将流过2秒,position增加量为(20,20),实际上,最终动画只持续了5秒
7. 暂停和恢复动画,Core Animation Guide 的例程如下
//暂停动画 -(void)pauseLayer:(CALayer*)layer { // 获取目前layer的时间 CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; //设置layer的speed为0,根据公示,layer的时间不在变动,自然动画就暂停了 layer.speed = 0.0; // 用timeOffset记录暂停的时间 layer.timeOffset = pausedTime; } //恢复动画 -(void)resumeLayer:(CALayer*)layer { CFTimeInterval pausedTime = [layer timeOffset]; // 恢复speed,之后layer的时间开始变动,重设beginTime和timeOffset
// 重设的目的是接下来调用convertTime:fromLayer:得到正确的值 layer.speed = 1.0; layer.timeOffset = 0.0; layer.beginTime = 0.0; //计算动画暂停了多长时间 CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; //设置beginTime, 根据公式 t = (tp - beginTime) * speed +offset, layer的时间总是落后superlayer,落后量是beginTime, 实际上就是layer的时间从暂停的那个时间点开始 layer.beginTime = timeSincePause; }