Core Animation Programming Guide - Changing a Layer's Default Behavior

Changing a Layer's Default Behavior

Core Animation 用行为对象实现了隐式动画行为。一个行为对象是一个遵循了 CAAction 协议并在一个 layer 上定义了一些相关行为的对象。所有的 CAAnimation 对象都实现了这个协议,而且就是这些对象无论什么时候一个 layer 属性改变通常都会被执行。

动画属性是行为的一个类型,但是你可以根据自己的需要定义行为。你需要定义你的行为对象而且要关联他们到你的 app 的 layer 对象。

Custom Action Objects Adopt the CAAction Protocol

为了创建你自己的行为对象,从你的类中选择一个实现 CAAction 协议并实现 runActionForKey:object:arguments: 方法。在这个方法中,使用可用的信息表现你想在 layer 中采用的任意行为。你可以使用这个方法为 layer 添加一个动画对象或表现其他的任务。

当你定义一个行为对象时,你必须决定怎么触发这个行为。一个行为的触发定义了你后来注册的行为的键。行为对象可以被以下的任意情景触发:

  • layer 任意一个属性值的改变。这个可以是 layer 属性的任一值,不局限于动画相关的。(你也可以用自定义的属性关联相应的行为,然后添加到你的 layer 中。)定义这个行为的键就是属性的名称。
  • layer 变成可见状态活着被加入到一个 layer 层次中。定义这个行为的键是 kCAOnOrderIn
  • layer 从一个层次中被移除。定义此行为的键是 kCAOnOrderOut
  • layer 将要被包括进一个过渡动画中。定义此行为的键是 kCATransition

Action Objects Must Be Installed On a Layer to Have an Effect

在一个行为被表现之前,layer 需要发现要执行的相关行为对象。layer 相关行为的键是正被修改的属性的名字或者是这个行为的唯一表示的特殊字符串。当一个有关的时间发生在 layer 上时,layer 会调用自己的 actionForKey: 方法为相关键搜索行为对象。你的 app 可以在搜索期间的一些点上插入,然后为这个相关的行为提供一个相关的对象。

Core Animation 按照以下顺序查询行为对象:

  1. 如果 laye 有一个实现了 actionForLayer:forKey: 方法但委托,layer 会调用这个方法。委托必须遵循下面的一条:
    • 为给定的键返回行为对象。
    • 如果它不处理这个行为则返回 nil,以便搜寻进行下去。
    • 当搜寻立刻结束时,返回 NSNull 对象。
  2. layer 在它的 actions 字典中查找键。
  3. layer 在 style 字典中查找包含这个键点 actions 字典。(换句话说,style 字典包含一个 actions 的键,它的值依然是一个字典。layer 在第二个字典中查找给定的键。)
  4. layer 调用它的 defaultActionForKey: 类方法。
  5. layer 表现被 Core Animation 定义的隐式行为。

如果你在任意一个相关的搜寻点上提供一个行为对象,layer 会停止 它但搜索,然后执行返回的行为对象。当 layer 发现一个行为对象时,它会掉用对象的 runActionForKey:object:arguments: 方法来表现动画。如果你正定义自己的遵循了 CAAction 协议的对象,你必须使用对象的方法的实现处理相关的行为。

你在哪里安置行为对象取决于你打算怎么修改 layer。

  • 仅仅在特定的环境下才可能会用的行为,或者已经使用了一个委托对象的 layer,提供一个委托然后实现它的 actionForLayer:forKey: 方法就行。
  • 对于不常使用委托的 layer 对象,把 action 添加到 layer 到 actions 字典。
  • 对于在 layer 对象上自定义的属性相关的行为,把行为包括进 layer 的 style 字典即可。
  • 对于上 layer 基础行为的行为,继承 layer 然后重写 defaultActionForKey: 方法即可。

代码 6-1 展示了用来提供行为对象的委托方法的实现。在这个例子中,委托寻找 layer 的 contents 属性的改变,然后以过渡动画把新的内容转换到 contents 属性上。

代码 6-1 Providing an action using a layer delegate object

-(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 functinWithName:kCAMediaTimingFunctionEaseIn];
		
		theAnimation.type = kCATransitioPush;
		
		theAnimation.subtype = kCATransitionFromRight;
	}
	
	return theAnimation;
}


Disable Actions Temporarily Using the CATransaction Class

你可以用 CATransaction 类暂时禁用 layer 行为。当你改变一个 layer 到属性时,Core Animation 通常创建一个隐式的事务对象来动画地表现改变。如果你不想动画地表现改变,你可以通过创建一个显式的事务然后设置它的 kCATransactionDisableActions 属性值为 true 来禁用隐式动画。代码 6-2 展示了当从一个 layer 树中移除 layer 时禁用动画的部分代码。

代码 6-2 Temporarily disabling a layer's actions

[CATransaction begin];

[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];

[aLayer removeFromSuperlayer];

[CATransaction commit];

关于使用事务对象管理动画行为的更多信息,相见 Explicit Transactions Let You Change Animation Parameters.

posted @ 2015-02-05 15:06  1oo1  阅读(217)  评论(0编辑  收藏  举报