Designing like you mean it
The big advantage of using constraints is that you no longer have to fiddle with coordinates to get your views to appear in the proper places. Instead, you can describe to Auto Layout how the views are related to each other and Auto Layout will do all the hard work for you. This is called designing by intent.
When you design by intent, you’re expressing what you want to accomplish but not necessarily how it should be accomplished. Instead of saying: “the button’s top-left corner is at coordinates (20, 230)”, you now say:
“The button is centered vertically in its superview, and it is placed at a fixed distance from the left edge of the superview.”
Using this description, Auto Layout can automatically calculate where your button should appear, no matter how big or small that superview is.
Other examples of designing with intent (and Auto Layout can handle all of these instructions):
“These two text fields should always be the same size.”
“These two buttons should always move together.”
“These four labels should always be right-aligned.”
This makes the design of your user interfaces much more descriptive. You simply define the constraints, and the system calculates the frames for you automatically.
You saw in the first section that even a layout with just a few views needs quite a bit of work to layout properly in both orientations. With Auto Layout you can skip all that effort. If you set up your constraints properly, then the layout should work without any changes in both portrait and landscape.
Another important benefit of using Auto Layout is internationalization. Text in German, for example, is infamous for being very long and getting it to fit into your labels can be a headache. Again, Auto Layout takes all this work out of your hands, because it can automatically resize your labels based on the content they need to display – and have everything else adapt with constraints.
Adding support for German, French, or any other language is now simply a matter of setting up your constraints, translating the text, and… that’s it!
The best way to get the hang of Auto Layout is to play with it, so that’s exactly what you will do in the rest of this tutorial.
Note: Auto Layout is not just useful for rotation; it can also easily scale your UI up and down to accommodate different screen sizes. It is no coincidence that this technology was added to iOS at the same time that the iPhone 5 and its taller screen came out! Auto Layout makes it a lot easier to stretch your apps’ user interfaces to fill up that extra vertical space on the iPhone 5. And who knows what will come of the rumored “iPad mini”… With Auto Layout you will be prepared for the future.
Close your current project and create a new project using the Single View Application template. Name it “Constraints”. This will be an iPhone project that does not use storyboards, but it does use Automatic Reference Counting.
Any new projects that you create with Xcode 4.5 automatically assume that you will be using Auto Layout, so you do not need to do anything special to enable it.
Click on ViewController.xib to open Interface Builder. Drag a new Round Rect Button onto the canvas. Notice that while you’re dragging, dashed blue lines appear. These lines are known as the guides:
There are guides around the margins of the screen, as well as in the center:
If you have used Interface Builder before, then you have no doubt seen these guides. They are helpful hints that make it easier to align stuff. With Auto Layout enabled, however, the guides have a different purpose. You still use them for alignment, but they also tell you where the new constraints will go.
Drop the button in the top-left corner against the blue guides. Now the nib looks like this:
There are two blue thingies attached to the button. These T-bar shaped objects are the constraints that are set on this button.
All the constraints are also listed in the Document Outline pane on the left-hand side of the Interface Builder window:
There are currently two constraints, a Horizontal Space between the button and the left edge of the main view, and a Vertical Space between the button and the top edge of the main view. The relationship that is expressed by these constraints is:
“The button always sits at the top-left corner in its superview.”
Now pick up the button and place it in the nib’s top-right corner, again against the blue guides:
The Horizontal Space constraint has changed. It is no longer attached to the button’s left side, but to its right.
When you place a button (or any other view) against the guides, you get a constraint with a standard size that is defined by the “HIG”, Apple’s iOS Human Interface Guidelines document. For margins around the edges, the standard size is a space of 20 points.
Even if you place the button where there is no guide, you still get a Horizontal or Vertical Space constraint to keep it in place. Try it out. Drag the button a bit to the left until you get something like this:
There is still a Horizontal Space constraint, but it’s larger now. In the Document Outline, you can see that it no longer has a standard space:
What constraints you get depend on where you place the button.
There is also a “center” constraint. Drag the button to the bottom center of the canvas, so that it snaps into place with the guides:
Notice that the Horizontal Space constraint has been replaced by a Center X Alignment constraint, which means that the button is always center-aligned with its superview, on the horizontal axis. There is still a Vertical Space constraint to keep the button away from the bottom of the view (again, using the standard margin).
Run the app and rotate it to landscape. Even in landscape mode, the button stays at the bottom center of the screen:
That’s how you express intent: “This button should always be at bottom center.” Notice that nowhere did you have to tell Interface Builder what the button’s coordinates are, only where you want it anchored in the view.
With Auto Layout, you’re no longer supposed to care about the exact coordinates of where you place your views on the canvas or what their size is. Instead, Auto Layout derives these two things from the constraints that you set (or that Interface Builder sets for you).
You can see this paradigm shift in the Size inspector for the button, which is now quite different:
With Auto Layout disabled, typing into the X, Y, Width or Height fields will change the position and size of the selected view. With Auto Layout enabled, you can still type new values into these fields, but that may not always have the effect you want. The view will move, but Interface Builder will also calculate new constraints based on your new values.
For example, change the Width value to 100. The canvas turns into something like this:
The Center X Alignment constraint has disappeared, and in its place is a Horizontal Space that glues the button to the left edge of the screen, as well as a new constraint on the button itself that forces it to have a width of 100 points (the blue bar below the button).
You can also see this new Width constraint in the Document Outline on the left:
Unlike the other constraints, which are between the button and its superview, the Width constraint only applies to the button itself. You can think of this as a constraint between the button and… the button.
Drag the button so that it snaps with the Center X Alignment constraint again.
Tip: Because changing the position and size in the Size inspector may mess up your constraints, I advise against doing this. Instead, if you want to make changes to the layout, change the constraints.
You may wonder why the button did not have a Width constraint before. How did Auto Layout know how wide to make the button without it?
Here’s the thing: the button itself knows how wide it must be. It calculates this based on its title text plus some padding for the rounded corners. If you set a background image on the button, it also takes that into account.
This is known as the intrinsic content size. Not all controls have this, but many do (UILabel is another example). If a view can calculate its own preferred size, then you do not need to set specific Width or Height constraints on it. You will see more of this later.
To return the button to its optimal size, select it and choose Size to Fit Content from the Editor menu. This gets rid of the explicit Width constraint and restores the button’s intrinsic content size.