美文网首页
CABasicAnimation闪回问题与隐式动画

CABasicAnimation闪回问题与隐式动画

作者: 过气的程序员DZ | 来源:发表于2020-07-23 17:09 被阅读0次

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提供的方法可以延长这个时间。
而我们开发者经常写的动画效果被称作显示动画。

相关文章

网友评论

      本文标题:CABasicAnimation闪回问题与隐式动画

      本文链接:https://www.haomeiwen.com/subject/jamhlktx.html