[译] Core Animation 编程指南 - 附录C:键值编码扩展

525

Core Animation 扩展了 NSKeyValueCoding 协议,因为它与 CAAnimationCALayer 类是关联的。该扩展给一些键添加了默认值,扩展了包装约定,给 CGPoint, CGRect, CGSize, 和 CATransform3D 类型添加了键路径支持。

符合键值编码的容器类

CAAnimation 和 CALayer 类是符合键值编码的容器类,这意味着你可以给任意键赋值。即使 someKey 是 CALayer 类为声明的属性,你也可以向下面这样给它赋值:

[theLayer setValue:[NSNumber numberWithInteger:50] forKey:@"someKey"];

你也可以获取任意键的值就像检索其他键的值一样。例如,你可以使用下面的代码,去获取之前给 someKey 路径赋的值:

someKeyValue = [theLayer valueForKey:@"someKey"];

OS X 说明:CAAnimation 和 CALayer 类会自动归档你给类实例的键设置的值,它支持 NSCoding 协议。

支持默认值

Core Animation 为键值编码添加了一个约定,通过该约定,类可以为没有赋值的键提供默认值。CAAnimation 和 CALayer 类通过使用 defaultValueForKey: 类方法来支持此约定。

若要为键提供默认值,请创建所需类的子类,并重写其 defaultValueForKey: 方法。你的该方法的实现,应该检查键参数,并返回一个合适的默认值。例 C-1 展示了一个图层对象通过实现 defaultValueForKey: 方法,来给 masksToBounds 属性提供默认值的示例。

例 C-1 实现 defaultValueForKey: 方法的示例:

+ (id)defaultValueForKey:(NSString *)key {
    if ([key isEqualToString:@"masksToBounds"])
         return [NSNumber numberWithBool:YES];
    return [super defaultValueForKey:key];
}

包装约定 (Wrapping Conventions )

当键的数据由标量值或 C 数据结构组成时,必须先将该类型包装在对象中,然后再将其分配给图层。同样,当访问该类型时,你必须检索一个对象,然后使用适当类的扩展打开适当的值。表 C-1 列出了常用的 C 类型和用来包装它们 Objective-C 类。

表 C-1 C 类型数据的包装类

C 类型 包装类
CGPoint NSValue
CGSize NSValue
CGRect NSValue
CATransform3D NSValue
CGAffineTransform NSAffineTransform (仅限 OS X)

支持键路径的数据结构

CAAnimation 和 CALayer 类允许你使用键路径来访问选中数据结构的字段值。该特性是一种便捷的方式,用来指定你想动画的数据结构的字段。你也可以将该约定和 setValue:forKeyPath:valueForKeyPath: 方法结合使用去设置和获取字段的值。

CATransform3D 键路径

你可以使用增强的键路径支持来检索包含 CATransform3D 数据类型的属性的特定转换值。要指定图层形变的全键值路径,你需要使用表 C-2 中字段键值的 transformsublayerTransform 的字符串值。例如,指定沿图层 z 轴 的旋转因子,你应该指定 transform.rotation.z 的值。

表 C-2 形变字段键值路径

字段键值 描述
rotation.x 设置为 NSNumber 对象,该对象的值是 x 轴上以弧度为单位的旋转。
rotation.y 设置为 NSNumber 对象,该对象的值是 y 轴上以弧度为单位的旋转。
rotation.z 设置为 NSNumber 对象,该对象的值是 z 轴上以弧度为单位的旋转。
rotation 设置为 NSNumber 对象,该对象的值是 z 轴上以弧度为单位的旋转。该字段与 rotation.z 等效。
scale.x 设置为 NSNumber 对象,其值是 x 轴的比例因子。
scale.y 设置为 NSNumber 对象,其值是 y 轴的比例因子。
scale.z 设置为 NSNumber 对象,其值是 z 轴的比例因子。
scale 设置为 NSNumber 对象,其值是所有三个比例因子的平均值。
translation.x 设置为 NSNumber 对象,其值是沿 x 轴的平移因子。
translation.y 设置为 NSNumber 对象,其值是沿 y 轴的平移因子。
translation.z 设置为 NSNumber 对象,其值是沿 z 轴的平移因子。
translation 设置为包 含NSSize 或 CGSize 数据类型的 NSValue 对象。该数据类型表示要在 x 轴和 y 轴上平移的量。

下面的例子,展示了你如何使用 setValue:forKeyPath: 方法修改图层。该例中将 x 轴的平移因子设置为 10 个点,会造成图层想指示的轴线偏移。

[myLayer setValue:[NSNumber numberWithFloat:10.0] forKeyPath:@"transform.translation.x"];

注意:使用键路径赋值与使用 Objective-C 的属性赋值并不相同。你不能使用属性符号来设置形变值。你必须在前面的键路径字符串中使用的 setValue:forKeyPath: 方法。

CGPoint 键路径

如果给定属性的值为 CGPoint 数据类型,你可以将表 C-3 中的一个字段名追加到属性中,以获取或设置该值。例如,你可以操作 position.x,来修改图层 position 属性 x 元素的值。

表 C-3 CGPoint 数据结构字段

结构字段 描述
x x 元素的点。
y y 元素的点。

CGSize 键路径

如果给定属性的值为 CGSize 数据类型,你可以将表 C-4 中的一个字段名追加到属性中,以获取或设置该值。

表 C-4 CGSize 数据结构字段

结构字段 描述
width width 元素的大小。
height height 元素的大小。

CGRect 键路径

如果给定属性的值为 CGRect 数据类型,你可以将表 C-5 (此处原文为 C-3,但我觉得应该是写错了,所以这里改成 C-5。) 中的一个字段名追加到属性中,以获取或设置该值。例如,你可以操作 bounds.size.width,来修改图层 bounds 属性 width 元素的值。

表 C-5 CGRect 数据结构字段

结构字段 描述
origin CGPoint 矩形的原点。
origin.x 矩形原点 x 元素的值。
origin.y 矩形原点 y 元素的值。
size CGSize 矩形的大小。
size.width CGSize 矩形的 width 元素的大小。
size.height CGSize 矩形的 height 元素的大小。