美文网首页iOS面试
为什么 View 的根 Layer 没有隐式动画?

为什么 View 的根 Layer 没有隐式动画?

作者: 王技术 | 来源:发表于2019-06-12 16:36 被阅读15次

    上一篇整理了 关于隐式动画的笔记

    我们知道根 layer 是不能做隐式动画的
    就像这样, 是没有动画效果的, 颜色瞬间就变化了

        self.view.layer.backgroundColor = [UIColor blueColor].CGColor;
    

    那么隐式动画是如何被禁用掉呢?
    我们知道 Core Animation 通常对 CALayer 的所有可动画的属性做动画
    但是 UIView 把它的根 layer 这个特性关闭了
    为了更好说明这一点,我们需要知道隐式动画是如何实现的。

    我们把改变属性时 CALayer 自动应用的动画称作行为
    当 CALayer 的属性被修改时候,它会调用 -actionForKey: 方法,传递属性的名称
    -actionForKey: 经过一波猛虎操作
    流程如下

    • 图层首先检测它是否有委托,并且是否实现 CALayerDelegate 协议指定的 -actionForLayer:forKey 方法
      如果有,直接调用并返回结果。
    • 如果没有委托,或者委托没有实现 -actionForLayer:forKey 方法
      图层接着检查包含属性名称对应行为映射的 actions 字典。
    • 如果 actions 字典没有包含对应的属性,那么图层接着在它的 style 字典接着搜索属性名
    • 最后,如果在 style 里面也找不到对应的行为,那么图层将会直接调用定义了每个属性的标准行为的-defaultActionForKey:方法。

    所以一轮完整的搜索结束之后,-actionForKey: 要么返回空(这种情况下将不会有动画发生)
    要么是 CAAction 协议对应的对象,最后 CALayer 拿这个结果去对先前和当前的值做动画

    于是这就解释了 UIView 是如何禁用根 Layer 隐式动画的:
    每个 UIView 都成为了根 layer 的 delegate,并且提供了 -actionForLayer:forKey 的实现方法
    当属性的改变不在一个事务中的时候返回值为空, 这种情况下将不会有动画发生
    当属性的改变在一个事务中的时候返回值非空, 这时候就会有动画

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        NSLog(@"Outside: %@", [self.layerView actionForLayer:self.layerView.layer forKey:@"backgroundColor"]);
        // 开启一个事务
        [UIView beginAnimations:nil context:nil];
        NSLog(@"Inside: %@", [self.layerView actionForLayer:self.layerView.layer forKey:@"backgroundColor"]);
        [UIView commitAnimations];
    }
    
    

    打印结果

    $ LayerTest[21215:c07] Outside: <null>
    $ LayerTest[21215:c07] Inside: <CABasicAnimation: 0x757f090>
    

    于是我们知道
    当属性在事务之外发生改变
    UIView 直接通过返回nil来禁用隐式动画
    但如果在事务范围之内
    根据动画具体类型返回相应的属性
    当然返回 nil 并不是禁用隐式动画唯一的办法
    CATransacition 有个方法叫做 +setDisableActions:
    可以用来对所有属性打开或者关闭隐式动画。如果在 [CATransaction begin] 之后添加下面的代码
    同样也会阻止动画的发生:

    [CATransaction setDisableActions:YES];
    

    相关文章

      网友评论

        本文标题:为什么 View 的根 Layer 没有隐式动画?

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