レイヤは、ビジュアルコンテンツの提供とアニメーションの管理に関して直接的な責任を負うほか、他のレイヤのコンテナとしての役割も果たし、これによりレイヤ階層を形成しています。
この章では、レイヤ階層と、階層内のレイヤの操作方法について説明します。
レイヤツリー階層とは?
ビューでのレイヤの表示
レイヤの階層への追加と階層からの削除
レイヤの位置とサイズの変更
サブレイヤの切り取り
Core Animationのレイヤツリー階層は、Cocoaのビュー階層に相当するものです。NSViewにスーパービューとサブビューがあるのと同様に、Core Animationレイヤにはスーパーレイヤとサブレイヤがあります。レイヤツリーには、次のようにビュー階層と同じ多くの利点があります。
モノリシックで複雑なサブクラス化を避け、よりシンプルなレイヤを使って複雑なインターフェイスを組み立てられます。レイヤには複雑な合成機能があり、この種の「スタッキング」に非常に適しています。
各レイヤは、そのスーパーレイヤの座標系に対して相対的な専用の座標系を指定します。レイヤが変換されると、そのサブレイヤもレイヤ内で変換されます。
レイヤツリーは動的です。アプリケーションを実行しながらレイヤの再設定ができます。レイヤの作成、ほかのレイヤのサブレイヤとしての追加、レイヤツリーからのレイヤの削除ができます。
Core Animationは、レイヤをウインドウに実際に表示する手段を提供しておらず、NSViewインスタンスによってレイヤをホストする必要があります。ビューとペアにすると、ビューで対象のレイヤに対するイベント処理機能を提供しながら、レイヤではコンテンツの表示機能を提供することができます。
NSViewインスタンスを、レイヤをホストできるように設定できます。レイヤツリーのルートレイヤを表示するには、ビューへのレイヤの挿入に示すように、ビューのレイヤを設定し、次にそのビューがレイヤを使うように設定します。
リスト 1 ビューへのレイヤの挿入
// theViewはウインドウの既存のビュー |
// theRootLayerはレイヤツリーのルートレイヤ |
[theView setLayer: theRootLayer]; |
[theView setWantsLayer:YES]; |
レイヤインスタンスをインスタンス化しただけでは、レイヤツリーにレイヤは挿入されません。表 1に示すメソッドを使って、レイヤツリーに対してレイヤの追加、挿入、置換、削除を行います。
メソッド | 結果 |
|---|---|
| レイヤを対象レイヤのサブレイヤ配列に追加します。 |
| レイヤを対象レイヤのサブレイヤとして、指定したインデックス位置に挿入します。 |
| レイヤを対象レイヤのサブレイヤ配列の指定したサブレイヤの下に挿入します。 |
| レイヤを対象レイヤのサブレイヤ配列の指定したサブレイヤの上に挿入します。 |
| 対象レイヤを、サブレイヤ配列または対象レイヤのスーパーレイヤのマスクプロパティから削除します。 |
| 対象レイヤのサブレイヤ配列内のレイヤを、指定した新しいレイヤに置き換えます。 |
レイヤの配列を使ってレイヤのサブレイヤを設定し、次に対象とするスーパーレイヤのサブレイヤのプロパティを設定することもできます。サブレイヤのプロパティを、レイヤオブジェクトが設定されている配列に設定する場合、それらのレイヤのスーパーレイヤがnilに設定されていることを確認する必要があります。
デフォルトでは、可視のレイヤツリーに対するレイヤの挿入と削除により、アニメーションが実行されます。あるレイヤがサブレイヤとして追加されると、アクション識別子kCAOnOrderInに対して親レイヤから返されたアニメーションが実行されます。あるレイヤがレイヤのサブレイヤから削除されると、アクション識別子kCAOnOrderOutに対して親レイヤから返されたアニメーションが実行されます。あるレイヤがサブレイヤ内で置き換えられると、アクション識別子kCATransitionに対して親レイヤから返されたアニメーションが実行されます。レイヤツリーの操作中にアニメーションを無効にしたり、任意のアクション識別子に対して使用されるアニメーションを変更したりできます。
レイヤの作成後、レイヤのジオメトリプロパティであるframe、bounds、position、anchorPoint、zPositionの値を単に変更することにより、プログラミングによってレイヤの位置とサイズを変更できます。
レイヤのneedsDisplayOnBoundsChangeプロパティがYESであれば、そのレイヤのコンテンツはレイヤの境界矩形が変わると再キャッシュされます。デフォルトでは、needsDisplayOnBoundsChangeプロパティはNOに設定されています。
デフォルトでは、プロパティframe、bounds、position、anchorPoint、zPositionを設定することにより、そのレイヤを新しい値に合わせてアニメーション化できます。
CALayerは、スーパーレイヤの移動またはサイズ変更を受けて自動的にサブレイヤの移動とサイズ変更を行うメカニズムを提供しています。多くの場合、単にレイヤの自動サイズ変更マスクを設定すれば、アプリケーションに対する適切な動作が提供されます。
レイヤの自動サイズ変更マスクは、ビット単位のOR演算子を使ってCAAutoresizingMask定数群を組み合わせ、その結果にレイヤのautoresizingMaskプロパティを組み合わせることで指定します。表 2に、各マスク定数と、それがレイヤのサイズ変更動作にどのように影響するかを示します。
自動サイズ変更マスク | 説明 |
|---|---|
| 設定されると、レイヤの高さは、スーパーレイヤの高さの変更に比例して変更されます。それ以外の場合、レイヤの高さは、スーパーレイヤの高さに対して変更されません。 |
| 設定されると、レイヤの幅は、スーパーレイヤの幅の変更に比例して変更されます。それ以外の場合、レイヤの幅は、スーパーレイヤの高さに対して変更されません。 |
| 設定されると、レイヤの左端は、スーパーレイヤの幅の変更に比例して再配置されます。それ以外の場合、レイヤの左端は、スーパーレイヤの左端に対して同じ位置を維持します。 |
| 設定されると、レイヤの右端は、スーパーレイヤの幅の変更に比例して再配置されます。それ以外の場合、レイヤの右端は、スーパーレイヤに対して同じ位置を維持します。 |
| 設定されると、レイヤの上端は、スーパーレイヤの高さの変更に比例して再配置されます。それ以外の場合、レイヤの上端は、スーパーレイヤに対して同じ位置を維持します。 |
| 設定されると、レイヤの下端は、スーパーレイヤの高さの変更に比例して再配置されます。それ以外の場合、レイヤの下端は、スーパーレイヤに対して同じ位置を維持します。 |
たとえば、レイヤの位置をそのスーパーレイヤの左下角に維持するには、マスクkCALayerMaxXMargin | kCALayerMaxYMarginを使います。ある軸に沿って複数のアスペクトを可変にした場合、サイズ変更の量は、それぞれのアスペクトに均等に配分されます。図 1に、定数値の位置を図で表します。
これらの定数の1つが省略されていると、レイヤのレイアウトはそのアスペクトにおいては固定されます。定数がマスクに含まれていると、レイヤのレイアウトはそのアスペクトにおいて可変になります。
サブクラス化により、CALayerのメソッドであるresizeSublayersWithOldSize:とresizeWithOldSuperlayerSize:をオーバーライドして、レイヤの自動サイズ変更動作をカスタマイズできます。レイヤのresizeSublayersWithOldSize:メソッドは、boundsプロパティが変更されるたびにレイヤによって自動的に呼び出され、各サブレイヤにresizeWithOldSuperlayerSize:メッセージを送ります。各サブレイヤは古い境界矩形サイズと新しいサイズを比較し、自動サイズ変更マスクに従ってその位置とサイズを調節します。
Cocoaビューのサブビューは、親ビューの境界矩形から外れているときには親ビューに合わせて切り取られます。レイヤの場合はこの制限を取り除き、親レイヤに対する相対的な位置に関係なく、サブレイヤ全体を表示できます。
レイヤのmasksToBoundsプロパティの値によって、サブレイヤが親に合わせて切り取られるかどうかが決まります。masksToBoundsプロパティのデフォルト値はNOであり、この場合サブレイヤは親に合わせて切り取られません。図 2に、layerAに対するmasksToBoundsの設定の結果と、それがlayerBとlayerCの表示にどのように影響するかを示します。
Last updated: 2007-12-06