Along with their own direct responsibilities for providing visual content and managing animations, layers also act as containers for other layers, creating a layer hierarchy.
This chapter describes the layer hierarchy and how you manipulate layers within that hierarchy.
What Is a Layer-Tree Hierarchy?
Displaying Layers in Views
Adding and Removing Layers from a Hierarchy
Repositioning and Resizing Layers
Clipping Sublayers
The layer-tree is the Core Animation equivalent of the Cocoa view hierarchy. Just as an instance of NSView
or UIView
has superview and subviews, a Core Animation layer has a superlayer and sublayers. The layer-tree provides many of the same benefits as the view hierarchy:
Complex interfaces can be assembled using simpler layers, avoiding monolithic and complex subclassing. Layers are well suited to this type of ‘stacking’ due to their complex compositing capabilities.
Each layer declares its own coordinate system relative to its superlayer's coordinate system. When a layer is transformed, its sublayers are transformed within it.
A layer-tree is dynamic. It can be reconfigured as an application runs. Layers can be created, added as a sublayer first of one layer, then of another, and removed from the layer-tree.
Core Animation doesn't provide a means for actually displaying layers in a window, they must be hosted by a view. When paired with a view, the view must provide event-handling for the underlying layers, while the layers provide display of the content.
The view system in iPhone OS is built directly on top of Core Animation layers. Every instance of UIView automatically creates an instance of a CALayer
class and sets it as the value of the view’s layer
property. To display custom layer content in a UIView instance you simply add the layers as sublayers of the view’s layer.
On Mac OS X you must configure an NSView
instance in such a way that it can host a layer. To display the root layer of a layer tree, you set a view's layer and then configure the view to use layers as shown in Table 2.
Listing 1 Inserting a layer into a view
// theView is an existing view in a window |
// theRootLayer is the root layer of a layer tree |
[theView setLayer: theRootLayer]; |
[theView setWantsLayer:YES]; |
Simply instantiating a layer instance doesn’t insert it into a layer-tree. Instead you add, insert, replace, and remove layers from the layer-tree using the methods described in .Table 1.
Method | Result |
---|---|
| Appends the layer to the receiver’s sublayers array. |
| Inserts the layer as a sublayer of the receiver at the specified index. |
| Inserts the layer into the receiver’s sublayers array, below the specified sublayer. |
| Inserts the layer into the receiver’s sublayers array, above the specified sublayer. |
| Removes the receiver from the sublayers array or mask property of the receiver’s superlayer. |
| Replaces the layer in the receiver’s sublayers array with the specified new layer. |
You can also set the sublayers of a layer using an array of layers, and setting the intended superlayer’s sublayers property. When setting the sublayers property to an array populated with layer objects you must ensure that the layers have had their superlayer set to nil
.
By default, inserting and removing layers from a visible layer-tree triggers an animation. When a layer is added as a sublayer the animation returned by the parent layer for the action identifier kCAOnOrderIn
is triggered. When a layer is removed from a layer’s sublayers the animation returned by the parent layer for the action identifier kCAOnOrderOut
is triggered. Replacing a layer in a sublayer causes the animation returned by the parent layer for the action identifier kCATransition
to be triggered. You can disable animation while manipulating the layer-tree, or alter the animation used for any of the action identifiers.
After a layer has been created, you can move and resize it programmatically simply by changing the value of the layer’s geometry properties: frame
, bounds
, position
, anchorPoint
, or zPosition
.
If a layer’s needsDisplayOnBoundsChange
property is YES, the layer’s content is recached when the layer’s bounds changes. By default the needsDisplayOnBoundsChange
property is no.
By default, setting the frame
, bounds
, position
, anchorPoint
, and zPosition
properties causes the layer to animate the new values.
CALayer
provides a mechanism for automatically moving and resizing sublayers in response to their superlayer being moved or resized. In many cases simply configuring the autoresizing mask for a layer provides the appropriate behavior for an application.
A layer's autoresizing mask is specified by combining the CAAutoresizingMask
constants using the bitwise OR
operator and the layer's autoresizingMask
property to the resulting value. Table 2 shows each mask constant and how it effects the layer's resizing behavior.
Autoresizing Mask | Description |
---|---|
| If set, the layer's height changes proportionally to the change in the superlayer's height. Otherwise, the layer's height does not change relative to the superlayer's height. |
| If set, the layer's width changes proportionally to the change in the superlayer's width. Otherwise, the layer's width does not change relative to the superlayer's width. |
| If set, the layer's left edge is repositioned proportionally to the change in the superlayer's width. Otherwise, the layer's left edge remains in the same position relative to the superlayer's left edge. |
| If set, the layer's right edge is repositioned proportionally to the change in the superlayer's width. Otherwise, the layer's right edge remains in the same position relative to the superlayer. |
| If set, the layer's top edge is repositioned proportionally to the change in the superlayer's height. Otherwise, the layer's top edge remains in the same position relative to the superlayer. |
| If set, the layer's bottom edge is repositioned proportional to the change in the superlayer's height. Otherwise, the layer's bottom edge remains in the same position relative to the superlayer. |
For example, to keep a layer in the lower-left corner of its superlayer, you use the mask kCALayerMaxXMargin | kCALayerMaxYMargin
. When more than one aspect along an axis is made flexible, the resize amount is distributed evenly among them. Figure 1 provides a graphical representation of the position of the constant values.
When one of these constants is omitted, the layer's layout is fixed in that aspect; when a constant is included in the mask the layer's layout is flexible in that aspect.
A subclass can override the CALayer
methods resizeSublayersWithOldSize:
and resizeWithOldSuperlayerSize:
to customize the autoresizing behavior for a layer. A layers resizeSublayersWithOldSize:
method is invoked automatically by a layer whenever bounds property changes, and sends a resizeWithOldSuperlayerSize:
message to each sublayer. Each sublayer compares the old bounds size to the new size and adjusts its position and size according to its autoresize mask.
When subviews of a Cocoa view lie outside of the parent view’s bounds, the views are clipped to the parent view. Layers remove this limitation, allowing sublayers to be displayed in their entirety, regardless of their position relative to the parent layer.
The value of a layer’s masksToBounds
property determines if sublayers are clipped to the parent. The default value of the masksToBounds
property is NO
, which prevents sublayers from being clipped to the parent. Figure 2 shows the results of setting the masksToBounds for layerA
and how it will affect the display of layerB
and layerC
.
© 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-13)