Introducing iOS Auto Layout
Auto Layout re-imagines the way developers create user interfaces. It’s provides a flexible and powerful system that describes how views and their content relate to each other and to the windows and superviews they occupy. In contrast to older design approaches, this technology offers incredible control over layout with a wider range of customization than frames, springs, and struts can express. Somewhat maligned by exasperated developers, Auto Layout has gained a reputation for difficulty and frustration, particularly when used through Interface Builder (IB).
That’s why this book exists. You’re about to learn Auto Layout mastery by example, with plenty of explanations and tips. Instead of struggling with class documentation, you’ll learn, in simple steps, how the system works and why it’s far more powerful than you first imagined. You’ll read about common design scenarios and discover best practices that make Auto Layout a pleasure rather than a chore to use.
Ready to get started? This chapter explains the basic concepts that lie behind Auto Layout and, for those who need to, how to opt out of Auto Layout until you’re ready to proactively take advantage of its many benefits.
Saying “No” to Auto Layout
Before diving into Auto Layout, it helps to know how to opt out. If you’re not yet ready to use these new features, you can easily switch off Auto Layout for individual storyboard and NIB files. All it takes is a simple switch to have Xcode revert you to the old style of Autosizing edits.
Here’s what you do:
- In Xcode, select any user interface document (storyboards or NIB file) from the Project Navigator (View > Navigators > Show Project Navigator).
- Open the File Inspector (View > Utilities > Show File Inspector).
- In the File Inspector, locate the Interface Builder Document section. Just below Document Versioning, you’ll find a Use Autolayout (or Use Auto Layout) check box, which you see in Figure 1-1.
Figure 1-1. Disable Auto Layout by unchecking the Use Autolayout (sic) or Use Auto Layout box in Xcode’s File Inspector. This option appears for both iOS and OS X projects. Although Apple documentation from 2012 and later now universally refers to the technology as Auto Layout, some references still use Autolayout as a single phrase.
- Uncheck this box to return Interface Builder to Autosizing behavior.
Under Autosizing, views use the autoresizingMask property to ensure that they resize correctly, such as when a device reorients or a user resizes a window. With Auto Layout disabled, you work with struts, springs, and autoresizingMasks. Figure 1-2 shows the Size Inspector (View > Utilities > Show Size Inspector) for a view with Auto Layout enabled (left) and disabled (right).
Figure 1-2. When Auto Layout is enabled (left), IB’s Size Inspector offers controls to adjust a view’s layout priorities and a provides list of constraints that mention the view. When disabled (right), the inspector reverts to the Autosizing struts and springs editor that correspond to a view’s autoresizingMask.
In code, Autosizing layout is even easier. You opt views out of Autosizing to participate in the new Auto Layout system. All views default to the older behavior even when modern runtimes use constraint-based layout. That’s because the runtime invisibly handles the translation between your old-style code and the new-style constraint system on your behalf.
When a view’s translatesAutoresizingMaskIntoConstraints property is set to YES (the default), the runtime uses that view’s autoresizing mask to produce matching constraints in the new Auto Layout system. The rules apply like they always did, even though the implementation details have been modernized.
Here’s what Apple has to say on the matter. This comment is from the UIView.h header file, and it’s essentially identical to the text in NSLayoutConstraint.h on OS X:
- By default, the autoresizing mask on a view gives rise to constraints that fully determine the view’s position. Any constraints you set on the view are likely to conflict with autoresizing constraints, so you must turn off this property first. IB will turn it off for you.
Autoresizing translation creates constraints to implement Autosizing rules and adds them to each superview. As you will see throughout this book, this pattern of generating constraints and adding them to a superview is quite common. In Chapter 2, “Constraints,” you learn exactly where each constraint should live. In this instance, you do no work yourself. The Auto Layout system handles all migration from autoresizing.
When you’re ready to move to Auto Layout, make sure that the constraints automatically generated for you don’t conflict with constraints you build on your own. Auto Layout constraints belong to the private NSAutoresizingMaskLayoutConstraint class. Constraints you build belong to the public NSLayoutConstraint class.
You may see instances of the resizing constraints mentioned in debugging logs produced by Xcode and should not be surprised by them. When conflicts do occur, check each view’s translatesAutoresizingMaskIntoConstraints property. Ensure that the Auto Layout system is not trying to create constraints that conflict with the ones that you are building yourself. In many cases, disabling autoresizing mask translation resolves basic conflicts.
That’s not to say that you must disable autoresizing entirely. You are welcome to mix and match autoresizing views with constraint-based layout as long as rules don’t clash. For example, you can load a NIB whose subviews are laid out using struts and springs and allow that view, in turn, to operate as a first-class member of the Auto Layout world (see Chapter 3, “Interface Builder Layout,” for an example). The key is encapsulation. As long as rules do not conflict, you can reuse complex views you have already established in your projects.