CABasicAnimation闪回问题
使用CABasicAnimation实现layer的移动
代码实现
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@end
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//动画1
CABasicAnimation *animation = [CABasicAnimation animation];
animation.keyPath = @"position.y";
animation.toValue = @600;
animation.duration = 1;
[_redView.layer addAnimation:animation forKey:nil];
......
}
在vc中用touchesBegin来触发动画,移动600的y。间隔1s时间,看看效果。
动画执行了,但是执行完又闪回到初始的地方了。其实是少写了两行代码。
//解决动画恢复到初始位置
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
根据字面解读这两行代码:
- 当完成时移除
-
设置一个填充方式
添加代码后看看效果
闪回的原因
三层树
查看官方文档,其实内部有三层layer树,分别是:model layer tree, presentation tree 和 render tree
- model layer tree:也就是layer树,相比其他两个树,app与之交互最多。并且里面的对象保存的都是动画的最终值。
- presentation tree:树中保存的对象包含动画运行中的当前状态值,也就是说动画过程中你在屏幕上看到的动画每一帧的值。不要修改这个树中的对象,但是你可以读取当前动画中的值,创建新的动画。如图中presentation tree中的对象与model layer tree中的对象是一一对应的。
- render tree:树中的对象提供真实的动画,并提供给Core Animation使用。也就是展示在屏幕上的效果。
我们再来看看removedOnCompletion和fillMode文档是怎么解释的
removedOnCompletion:
大致意思:
默认值是YES,在目标layer的动画结束后移除。
但是没说操作的是哪个layer树。但进入CAAnimation.h中(command+鼠标左键),看到了一段注释:image.png
==removed from the render tree==,证明移除的是removed树上的对象。
fillMode
动画结束时,接受者展示是被冻结还是移除掉。默认值是移除,而我们设置的是展示最后的状态。
总结
通过上面的这些信息,本人推断显示屏幕上的是从render tree中读取的值,而render tree在动画的不同阶段分别读取的是model layer tree和presentation tree中的值。
- 开始动画之前:读取model layer tree的最终值(就是初始化设定的值,可以打印layer的frame,动画结束后与动画开始之前frame是一样的)。
- 开始动画:读取presentation tree中的值。
- 动画结束:
- 当removedOnCompletion和fillMode都设置默认值时,读取model layer tree中的值,也就是闪回原来的位置。
- 当按照上面修改removedOnCompletion和fillMode的值时,保持presentation tree中的值,让render tree读取presentation tree的值。这样就可以保持动画结束后的状态。
以上是本人分析的结果,如有不严谨的地方,还请指出。
隐式动画
在设置layer背景色的时候,弱弱的能看到一个颜色变化的动画。由于时间比较短,很多人没有注意到。
代码:_layer.backgroundColor = [UIColor orangeColor].CGColor;
设置这行代码后仔细观察效果,会看到颜色有个渐变过程,因为gif图截取后看的不明显,大家可以自己用代码实现一下,并仔细观察观察。
想要明显看到颜色的变化可以对这个代码进行CATransaction包装一下:
[CATransaction begin];
[CATransaction setAnimationDuration:2.0];
_layer.backgroundColor = [UIColor orangeColor].CGColor;
[CATransaction commit];
看看效果:
隐式动画是系统对layer层自动提供的,时间是0.25秒。通过CATransaction提供的方法可以延长这个时间。
而我们开发者经常写的动画效果被称作显示动画。
网友评论