圖層的行爲在以下情況發生的時候被觸發:從圖層樹裏面插入或者刪除一個圖層,圖層的屬性值被修改了,或者程序顯式要求。通常情況下,行爲觸發器是動畫顯示的結果所在。
1.1 行爲對象的角色
一個行爲對象是一個通過CAAction協議響應行爲標識符的對象。行爲標識符使用標準圓點分隔的關鍵路徑來命名。圖層負責把行爲標識符映射到特定的行爲對象。當一個特定標識符的行爲對象被確定的時候,它會發送一個CAAction協議定義的消息。
CALayer類提供了默認的CAAnimation的行爲對象實例,一個兼容類所有動畫層屬性CAAction協議。表1中CALayer同樣定義了以下沒有直接對應到屬性的行爲觸發器和他們的行爲標識符。
表 1 Action 觸發器和相應的標示符
Trigger |
Action identifier |
一個layer被插入一個可見的layer樹,或者layer的hidden屬性被設爲NO |
kCAOnOrderIn |
一個layer被從一個可見的layer樹中移除,或者layer的hidden屬性被設爲YES |
kCAOnOrderOut |
使用replaceSublayer:with:方法將一個可見樹中的layer替換 |
kCATransition |
1.2 已定義搜索模式的行爲鍵值
當一個行爲觸發器發生的時候,圖層的actionForKey:方法被調用。此方法返回一個行爲對象,對應的標識符作爲參數,或如果行爲對象不存在的話返回nil。
當CALayer爲一個標識符實現的actionForKey:方法被調用的時候,以下的搜索模式將會被用到:
- 如果一個圖層有委託,那方法actionForLayer:forKey:的實現將會被調用,把圖層和行爲標識符作爲參數。委託的actionForLayer:forKey:的實現需要響應如下:
- 返回一個行爲標識符對應的行爲對象。
- 返回nil,當無法處理行爲標識符的時候。
- 返回NSNull,當無法處理行爲標識符,而且搜索需要被終止的時候。
- 圖層的actions字典被搜索以便找到一個和行爲標識符對應的對象。
- 圖層的style屬性被搜索以便找到一個包含行爲標識符的actions字典。
- 圖層類發生一個defaultActionForKey:的消息。它將會返回一個和標識符對應的行爲對象,如果不存在的話則返回nil。
1.3 採用CAAction協議
CAAction協議定義了行爲對象如何被調用。實現CAAction協議的類包含一個方法runActionForKey:object:arguments:。
當行爲對象收到一個runActionForKey:object:arguments:的消息時,行爲標識符、行爲發生所在的圖層、額外的參數字典會被作爲參數傳遞給方法。
通常行爲對象是CAAnimation的子類實例,它實現了CAAction協議。然而你也可以返回任何實現了CAAction協議的類對象。當實例收到runActionForKey:object:arguments:的消息時,它需要執行相應的行爲。
當CAAnimation實例受到消息runActionForKey:object:arguments:的時候,它把自己添加到圖層的動力裏面,觸發動畫的執行(查看代碼1)。
代碼 1 runActionForKey:object:arguments: 的實現:啓動動畫
- (void)runActionForKey:(NSString *)key
object:(id)anObject
arguments:(NSDictionary *)dict
{
[(CALayer *)anObject addAnimation:self forKey:key];
}
1.4 重載隱式動畫
你可以爲行爲標識符提供隱式的動畫,通過插入一個CAAnimation的實例到style字典裏面的actions的字典裏面,通過實現委託方法actionForLayer:forKey:或者繼承圖層類並重載defaultActionForKey:方法返回一個相應的行爲對象。
代碼2的示例通過委託替換contents屬性的隱式動畫。
代碼 2 contents 屬性的隱式動畫
- (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;
}
代碼3的示例使用actions字典模式禁用sublayers屬性的默認動畫。
代碼 3 sublayers 屬性的隱式動畫
// get a mutable version of the current actions dictionary
NSMutableDictionary *customActions=[NSMutableDictionary dictionaryWithDictionary:[theLayer actions]];
// add the new action for sublayers
[customActions setObject:[NSNull null] forKey:@"sublayers"];
// set theLayer actions to the updated dictionary
theLayer.actions=customActions;
1.5 暫時禁用行爲
默認情況下,你任何時候改變一個可動畫顯示的屬性時,相應的動畫將會伴隨發生。
在修改圖層屬性的時候,你可以通過使用事務暫時禁用行爲。查看“暫時禁用圖層的行爲”部分來獲取更多信息。