美文网首页
Layer Animation

Layer Animation

作者: ienos | 来源:发表于2020-04-23 00:17 被阅读0次

    默认情况下, Layer的大部分标准属性都可以执行动画, 无论是添加一个 CAAnimation 到 Layer (显示动画),还是为属性指定一个动作然后修改它(隐式动画)

    接下来, 将讨论如何子类化 CALayer 并添加我们自己的属性, 让它执行相应的动画. 因为可能涉及到以下需求:
    1.修改一个属性,间接动画一个或者多个标准属性
    2.修改一个属性,触发 Layer 的重绘方法
    3.去除标准属性的隐式动画效果

    一、间接动画

    在非动画属性的 setter 方法里面,改变一个或者多个动画属性的值

    二、去除隐式动画

    ( 1 ) 重写 layer 方法

    - (id<CAAction>)actionForKey:(NSString *)event {
    //    if ([event isEqualToString:@"position"]) {
    //        return nil;
    //    }
    }
    

    ( 2 ) 在改变属性时调用

    [CATransaction begin]; //开启事务
    [CATransaction setDisableActions:YES];   //禁用隐式动画
    layer.frame = CGRectOffset(layer.frame, 100, 0);
    

    能显式的关闭这个事务中的 action 查询操作。
    关闭了查询也就是关闭了动画效果,属性值的变化就会立即生效,而没有动画效果了

     [CATransaction commit]; //提交事务
    

    三、自定义属性, 通过 setter 方法触发 Layer 的重绘方法(也可用于非可视化属性的动态变化 )

    ( 1 ) 在.h文件添加对象类型属性, 并在@implementation里面设置该属性为@dynamic definition

    • CALayer 具有为任何被声明成dynamic的属性生成 setter 和 getter 的能力
    • dynamic 告诉编译器, 属性的 setter 和 getter 方法由用户自己实现, 不自动生成
    • 编译通过, 若调用 setter、getter 方法且用户无自定义将会造成崩溃

    ( 2 ) 让 CALayer 监控自定义的属性, 使得自定义属性在发生改变时, 调用 - dispaly-actionForKey

    + (BOOL)needsDisplayForKey:(NSString *)key {
        if ([key isEqualToString:@"definition"]) {
            return true;
        }
        return [super needsDisplayForKey:key];
    }
    

    ( 3 ) 给自定义的属性添加动态变化的效果

    - (id<CAAction>)actionForKey:(NSString *)event { 
       // 给自定义的属性添加动态变化的效果
       // 该方法是在赋值之前调用, 所以在无初始值的情况下, 第一次display 为 nil , 将会造成无动画效果(解决方法: 附期望的初值)
       // fromValue : 这里的 modelLayer 和 presentationLayer 的值相同
        if ([event isEqualToString:@"definition"]) {
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:event];
            animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
            animation.fromValue = self.definition;
            return animation;
        }
        return [super actionForKey:event];
    }
    

    ( 4 ) 在- display里面调用重绘方法

    - (void)display {
        // 当设置某个 CALayer 的某个属性, 实际上设置的是 modelLayer 的值
        // modelLayer 表示正在进行的动画结束时, layer所到达的最终状态
        // presention Layer 是 modelLayer 的拷贝, 但它所表示的是当前值, 中间动画状态的值
        // 在这里调用重绘方法
        NSLog(@"display, definition: %@", [[self presentationLayer] definition]);
    }
    

    相关文章

      网友评论

          本文标题:Layer Animation

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