レイヤアクションは、レイヤがレイヤツリーに挿入される場合とツリーから削除される場合、レイヤプロパティの値が変更される場合、アプリケーションから明示的に要請がある場合に発生します。通常は、アクショントリガの結果としてアニメーションが表示されます。
アクションとは何か?
アクションオブジェクト検索パターン
CAActionプロトコル
暗黙的なアニメーションのオーバーライド
アクションを一時的に無効にする
アクションオブジェクトは、CAActionプロトコルを通じてアクション識別子に応答するオブジェクトです。アクション識別子は、標準的なドットで区切られたキーパスを使って命名されます。レイヤは、アクション識別子を適切なアクションオブジェクトにマップする役割を果たします。識別子に対応するアクションオブジェクトが見つかると、レイヤはそのオブジェクトにCAActionプロトコルで定義されているメッセージを送ります。
CALayerクラスは、デフォルトのアクションオブジェクト(CAActionプロトコルに準拠したクラスであるCAAnimationのインスタンス)をアニメーション化可能なレイヤプロパティに対して提供します。CALayerはまた、直接的にはプロパティにリンクしていない次のアクショントリガと、表 1に示すアクション識別子も定義しています。
トリガ | アクション識別子 |
|---|---|
レイヤが可視のレイヤツリーに挿入されるか、 | アクション識別子定数 |
レイヤが可視のレイヤツリーから削除されるか、 | アクション識別子定数 |
レイヤが | アクション識別子定数 |
アクショントリガが発生すると、レイヤのactionForKey:メソッドが呼び出されます。このメソッドは、パラメータとして渡されたアクション識別子に対応するアクションオブジェクトを返すか、アクションオブジェクトが存在しない場合はnilを返します。
ある識別子の照合のためにactionForKey:のCALayerの実装が呼び出されると、次の検索パターンが使われます。
レイヤにデリゲートがあり、メソッドactionForLayer:forKey:が実装されていればこれが呼び出され、パラメータとしてレイヤとアクション識別子が渡されます。デリゲートのactionForLayer:forKey:の実装は、次のように応答する必要があります。
アクション識別子に対応するアクションオブジェクトを返す。
アクション識別子を処理しない場合はnilを返す。
アクション識別子を処理せず、検索を終了する必要がある場合は、NSNullを返す。
レイヤのactionsディクショナリを対象に、アクション識別子に対応するオブジェクトが検索されます。
目的の識別子が含まれているactionsディクショナリを対象に、レイヤのstyleプロパティが検索されます。
レイヤのクラスにdefaultActionForKey:メッセージが送られます。識別子に対応するアクションオブジェクトを返すか、または見つからない場合はnilを返します。
CAActionプロトコルは、アクションオブジェクトがどのように呼び出されるかを定義します。CAActionプロトコルを実装するクラスには、シグネチャrunActionForKey:object:arguments:のメソッドがあります。
アクションオブジェクトがrunActionForKey:object:arguments:メッセージを受け取るときには、アクション識別子、そのアクションが発生すべきレイヤ、オプションのパラメータのディクショナリが渡されます。
通常、アクションオブジェクトはCAAnimationサブクラスのインスタンスであり、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]; |
} |
アクション識別子に対して別の暗黙的なアニメーションを指定することができます。これを行うには、CAAnimationのインスタンスをactionsディクショナリまたはstyleディクショナリのアクションディクショナリに挿入するか、デリゲートメソッドactionForLayer:forKey:を実装するか、レイヤクラスをサブクラス化してdefaultValueForKey:をオーバーライドし、該当するアクションオブジェクトを返すようにします。
リスト 2に示す例では、デリゲートを使ってcontentsプロパティのデフォルトの暗黙的なアニメーションを置き換えています。
リスト 2 コンテンツプロパティの暗黙的なアニメーション
- (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 サブレイヤプロパティの暗黙的なアニメーション
[theLayer.actions setObject:[NSNull null] forKey:@"sublayers"]; |
トランザクションを使ってレイヤのプロパティを変更するときに、アクションを一時的に無効にすることができます。詳細についてはレイヤアクションを一時的に無効にするを参照してください。
Last updated: 2007-12-06