NSView
provides the classic "struts and springs" model of repositioning views relative to their superlayer when it resizes. While layers support this model, Core Animation on Mac OS X provides a more general layout manager mechanism that allows developers to write their own layout managers. A custom layout manager (which implements the CALayoutManager
protocol) can be specified for a layer, which then assumes responsibility for providing layout of the layer's sublayers.
This chapter describes the constraints layout manager and how to configure a set of constraints.
iPhone OS Note: The CALayer
class in iPhone OS only supports the “struts and springs” positioning model, it does not provide custom layout managers.
Constraint-based layout allows you to specify the position and size of a layer using relationships between itself its sibling layers or its superlayer. The relationships are represented by instances of the CAConstraint
class that are stored in an array in the sublayers’ constraints
property.
Figure 1 shows the layout attributes you can use when specifying relationships.
When using constraints layout you first create an instance of CAConstraintsLayoutManager
and set it as the parent layer’s layout manager. You then create constraints for the the sublayers by instantiating CAConstraint
objects and adding them to the sublayer’s constraints using addConstraint:
. Each CAConstraint
instance encapsulates one geometry relationship between two layers on the same axis.
Sibling layers are referenced by name, using the name
property of a layer. The special name superlayer
is used to refer to the layer's superlayer.
A maximum of two relationships must be specified per axis. If you specify constraints for the left and right edges of a layer, the width will vary. If you specify constraints for the left edge and the width, the right edge of the layer will move relative to the superlayer’s frame. Often you’ll specify only a single edge constraint, the layer’s size in the same axis will be used as the second relationship.
The example code in Listing 1 creates a layer, and then adds sublayers that are positioned using constraints. Figure 2 shows the resulting layout.
Listing 1 Configuring a layer’s constraints
// create and set a constraint layout manager for theLayer |
theLayer.layoutManager=[CAConstraintLayoutManager layoutManager]; |
CALayer *layerA = [CALayer layer]; |
layerA.name = @"layerA"; |
layerA.bounds = CGRectMake(0.0,0.0,100.0,25.0); |
layerA.borderWidth = 2.0; |
[layerA addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY |
relativeTo:@"superlayer" |
attribute:kCAConstraintMidY]]; |
[layerA addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX |
relativeTo:@"superlayer" |
attribute:kCAConstraintMidX]]; |
[theLayer addSublayer:layerA]; |
CALayer *layerB = [CALayer layer]; |
layerB.name = @"layerB"; |
layerB.borderWidth = 2.0; |
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintWidth |
relativeTo:@"layerA" |
attribute:kCAConstraintWidth]]; |
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX |
relativeTo:@"layerA" |
attribute:kCAConstraintMidX]]; |
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY |
relativeTo:@"layerA" |
attribute:kCAConstraintMinY |
offset:-10.0]]; |
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY |
relativeTo:@"superlayer" |
attribute:kCAConstraintMinY |
offset:+10.0]]; |
[theLayer addSublayer:layerB]; |
Here’s what the code does:
Creates an instance of CAConstraintsLayoutManager
and sets it as the layoutManager
property of theLayer
.
Creates an instance of CALayer
(layerA
) and sets the layer’s name
property to “layerA”.
The bounds of layerA
is set to a (0.0,0.0,100.0,25.0).
Creates a CAConstraint
object, and adds it as a constraint of layerA
.
This constraint aligns the horizontal center of layerA
with the horizontal center of the superlayer.
Creates a second CAConstraint
object, and adds it as a constraint of layerA
.
This constraint aligns the vertical center of layerA
with the vertical center of the superlayer.
Adds layerA
as a sublayer of theLayer
.
Creates an instance of CALayer
(layerB
) and sets the layer’s name
property to “layerB”.
Creates a CAConstraint
object, and adds it as a constraint of layerA
.
This constraint sets the width of layerB
to the width of layerA
.
Creates a second CAConstraint
object, and adds it as a constraint of layerB
.
This constraint sets the horizontal center of layerB
to be the same as the horizontal center of layerA
.
Creates a third CAConstraint
object, and adds it as a constraint of layerB
.
This constraint sets the top edge of layerB
10 points below the bottom edge of layerA
.
Creates a fourth CAConstraint
object, and adds it as a constraint of layerB
.
This constraint sets the bottom edge of layerB
10 points above the bottom edge of the superlayer.
Warning: It is possible to create constraints that result in circular references to the same attributes. In cases where the layout is unable to be computed, the behavior is undefined.
© 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-13)