Adopting Auto Layout
Views that are aware of Auto Layout can coexist in a window with views that are not. That is, an existing project can incrementally adopt Auto Layout features.
This works through the property
translatesAutoresizingMaskIntoConstraints. When this property is
YES, which it is by default, the autoresizing mask of a view is translated into constraints. For example, if a view is configured as in Figure 6-1 and
YES, then the constraints
V:|-20-[button(20)] are added to the view’s superview. The net effect is that unaware views behave as they did in versions of OS X prior to 10.7.
If you move the button 15 points to the left (including by calling
setFrame: at runtime), the new constraints would be
For views that are aware of Auto Layout, in most circumstances you will want
translatesAutoresizingMaskIntoConstraints to be
NO. This is because the constraints generated by translating the autoresizing mask are already sufficient to completely specify the frame of a view given its superview’s frame, which is generally too much. For example, this will prevent a button from automatically assuming its optimal width when its title is changed.
The principal circumstance in which you should not call
setTranslatesAutoresizingMaskIntoConstraints: is when you are not the person who specifies a view’s relation to its container. For example, an
NSTableRowView instance is placed by
NSTableView. It might do this by allowing the autoresizing mask to be translated into constraints, or it might not. This is a private implementation detail. Other views on which you should not call
setTranslatesAutoresizingMaskIntoConstraints: include an
NSTableCellView, a subview of
NSTabViewItem’s view, or the content view of an
NSBox. For those familiar with classic Cocoa layout: If you would not call
setAutoresizingMask: on a view in classic style, you should not call
setTranslatesAutoresizingMaskIntoConstraints: under Auto Layout.
If you have a view that does its own custom layout by calling
setFrame:, your existing code should work. Just don’t call
setTranslatesAutoresizingMaskIntoConstraints: with the argument
NO on views that you place manually.
To provide additional compatibility, the entire constraint-based layout system is not active at all until you install a constraint on a view. Typically this is not something you should be concerned with, but if your previous layout was delicate in that you had problems you fixed by figuring out in what order the framework called methods, you may find that these problems are back under constraint-based layout. Hopefully in most cases the easiest solution will be to adopt constraint-based layout for the affected views. If you’re a framework author providing custom views and want to avoid engaging constraint-based layout in a window, you can do any necessary work in
updateConstraints. This method is not called until constraint-based layout is engaged. Furthermore, one of the purposes of
updateConstraints is that it has a well-defined timing, similar to
awakeFromNib, so you may find your problems are easier to resolve under Auto Layout.
There is an edge case to be aware of. When you implement a view, you might implement all your constraint setup in a custom
updateConstraints method. However, because the constraint based system engages lazily, if nothing installs any constraint, your
updateConstraints method will never be invoked. To avoid this problem, you can override
requiresConstraintBasedLayout to return
YES to signal that your view needs the window to use constraint based layout.
© 2012 Apple Inc. All Rights Reserved. (Last updated: 2012-09-19)