43

CoreAnimation编程指南翻译(七):修改图层的默认行为

 5 years ago
source link: http://www.devzhang.cn/2019/03/10/修改图层的默认行为/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Core Animation 使用操作对象实现图层的隐式动画. 操作对象遵循 CAAction 协议, 定义了在图层上执行时的相关行为. 所有的 CAAnimation 对象都实现了 CAAction 协议, 用于在图层属性发生变化时执行动画.

操作可以实现任意的自定义行为, 动画只是其中一种. 要实现自定义操作需要先创建操作对象, 并将其关联到图层.

自定义操作对象

自定义操作对象需要遵循 CAAction 协议, 并实现 runActionForKey:object:arguments: 方法. 在该方法中, 实现要对图层执行的操作, 比如添加动画或执行其他任务.

定义操作对象时, 还必须指定操作何时被触发. 操作触发器定义了不同的key对应不同的触发点. 操作可在以下情况下被触发:

  • 图层的属性发生变化时. 可以是图层的任何属性, 包括通过KVC添加的自定义属性. 此时操作触发点的key为属性名.
  • 图层变为可见状态, 或是被添加到图层树中. 此时操作触发点的key为 kCAOnOrderIn .
  • 图层从图层树中被移除. 此时操作触发点的key为 kCAOnOrderOut .
  • 图层将要执行过渡动画. 此时操作触发点的key为 kCATransition .

在图层上添加操作

操作只有被添加到图层上之后才能生效. 当图层上有事件发生时, 首先会调用 actionForKey: 方法查找与指定key相关联的操作对象. 在此查找过程中, 有几个合适的时机可以用来提供相关的操作对象.

Core Animation 按照以下顺序查找操作对象:

  1. 如果图层设置了delegate, 并且delegate实现了 actionForLayer:forKey: 方法, 则该方法中必须执行以下操作之一:

    • 返回与指定key相关联的操作对象.
    • 返回 nil 表示不处理, 此时会继续查找.
    • 返回 NSNull 对象, 此时查找立即结束.
  2. 在图层的 actions 字典中查找指定的key.

  3. 在图层的 style 字典中查找包含指定key的actions字典(也就是说, style 字典中包含一个名为 action 的key, 其value也是一个字典. 图层在这个字典中查找指定的key).
  4. 调用 defaultActionForKey: 方法.
  5. 如果 Core Animation 定义了隐式操作, 则执行该操作.

如果在上面的任意时机提供了操作对象, 图层会停止查找并执行返回的操作对象. 当找到操作对象后, 会调用该操作对象的 runActionForKey:object:arguments: 方法. 如果查找到的操作对象为 CAAnimation 类型, 则可以使用该方法的默认实现来执行动画. 如果是自定义操作对象, 则必须实现该方法执行自定义操作.

对应上面操作对象的查找过程, 图层上有多个属性或方法可以关联操作对象. 关联操作对象的正确时机取决于要如何修改图层:

  • 只在特定情况下执行操作, 或是给图层设置了delegate, 此时使用 actionForLayer:forKey: 方法.
  • 对于未设置delegate的图层, 使用图层的 actions 字典.
  • 为图层上的自定义属性添加操作, 使用图层的 style 字典.
  • 图层基本行为相关的操作, 自定义图层子类, 并重写 defaultActionForKey: 方法.

Listing 6-1 展示了使用delegate提供操作对象的方法实现, 示例中替换了图层的 contents , 并使用了过渡动画.

Listing 6-1使用delegate提供操作对象

- (id<CAAction>)actionForLayer:(CALayer *)theLayer
                        forKey:(NSString *)theKey {
    CATransition *theAnimation=nil;
 
    if ([theKey isEqualToString:@"contents"]) {
 
        theAnimation = [[CATransition alloc] init];
        theAnimation.duration = 1.0;
        theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        theAnimation.type = kCATransitionPush;
        theAnimation.subtype = kCATransitionFromRight;
    }
    return theAnimation;
}

禁用操作

使用 CATransaction 类可以临时禁止图层执行操作. 当修改图层部分属性时, Core Animation 会提供隐式动画. 如果不需要隐式动画, 可以显式创建一个事务, 并将其 kCATransactionDisableActions 属性设置为 true . Listing 6-2 展示了在移除图层时禁用动画的代码片段.

Listing 6-2临时禁止图层使用操作

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];

更多关于事务的信息, 请参阅 使用显示事务修改动画参数 .


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK