This tutorial is an excerpt from our book series iOS App Development for Non-Programmers, available in the iBookStore for the iPad, and on Amazon.
Part 1 discusses the two layout options, then dives in on springs and struts. Part 2 discusses the new Auto Layout option available in iOS 6 and later. Part 3 takes tutorial on Auto Layout to the next level!
Auto Layout is a descriptive layout system that supports more complex user-interface layouts. As you will learn when we cover creating multi-lingual applications later in this series, it also makes internationalization much easier. Auto Layout is a complete replacement for springs and struts, but remember that it can only be used in Apps running on iOS 6 or later!
With Auto Layout, you create descriptions known as constraints that specify how you want your controls positioned and resized. You can specify the relative size and position of a control with respect to the view that contains it or with respect to other controls in the view. You can also use constraints to specify geometric properties of a control such as height and width. From these constraints, Auto Layout calculates the appropriate position and size of your controls at run time when the view first loads and when the size of the view changes, such as when the user changes the device orientation.
Let’s dive in with an example so you can see first hand how this works. To get the sample code for this tutorial, click on the following link:
Tutorial Samples
Figure 8.14 Position the button at the bottom of the scene until you see horizontal and vertical guide lines.
Notice the long vertical line in the center of the scene, as well as the small “I” bar between the bottom of the button and the bottom of the scene (Figure 8.15). These are constraints that Interface Builder automatically added to the view.Figure 8.15 When you select a UI control, its constraints are displayed in the design surface.
If you select a constraint, you can see more details about it. Although you can click on a constraint directly in the design surface to select it, it’s usually easier to go to the Size Inspector where constraints for the currently selected control are also shown.
Figure 8.16 The Size Inspector displays constraints for the object currently selected in the design surface.
These specific constraints were added by Interface Builder because you dropped the button on the view when the center-alignment and bottom-alignment guidelines appeared.
Figure 8.17 Hover over a constraint in the Size Inspector to see the corresponding constraint in the design surface.
Figure 8.18 Constraints in the Document Outline pane
Figure 8.19 The button centered at the bottom of the view
When you center a button at the bottom of a view using springs and struts, it hard-codes the position of the button to that location. In order to keep the button centered when the device orientation changes, you have to explicitly specify this by selecting the appropriate struts in the Size Inspector.
With Auto Layout, all you had to do was place the button in the bottom center of the view and it positioned itself automatically. This is much easier! Now let’s take a closer look at the constraints that are automatically created for you by Interface Builder.
Figure 8.21 The button’s vertical constraint is highlighted.
Figure 8.22 Vertical-space constraint attributes
In the context of the vertical-space constraint, this indicates if the vertical space is less than or equal to, equal to, or greater than or equal to the specified amount of space.
The constraint shown in Figure 8.22 could be read as “Require the vertical space between the bottom of the button and the bottom of the view to be the standard spacing for iOS Apps.”
When you change the size or position of a control at design time, Interface Builder deletes old constraints and adds new ones based on your changes. Let’s take a look at some other constraints that are created automatically.
Figure 8.23 The button in the bottom left corner of the view
This deletes the Center X Alignment constraint and creates a Horizontal Spaceconstraint, which can be seen in the Document Outline pane (Figure 8.24).
Figure 8.24 The Horizontal Space constraint
Figure 8.25 The Leading Space constraint
The constraint is more generically called Horizontal Space in the Document Outline pane, and more specifically called a Leading Space constraint in the Size Inspector.
In English, leading space indicates the space between the left side of the view and the left side of the UI control. In right-to-left languages such as Hebrew and Arabic, it indicates the space between the right side of the view and the right side of the control.
Figure 8.26 View the leading-space constraint attributes.
Figure 8.27 The constraint’s Direction attribute
Notice the Direction attribute, which lets you specify the direction of the horizontal space. The choices are:
Figure 8.28 Position the button in the bottom-right corner.
Figure 8.29 The Trailing Space constraint
The trailing-space constraint has the same attributes as the leading-space constraint, so we don’t need to go to the Attributes Inspector to check them out.
Figure 8.30 Position the button at the top center
Figure 8.31 The new Top Space constraint
The top-space constraint has the same attributes as the bottom-space constraint, so we don’t need to go to the Attributes Inspector.
The constraints that are created automatically for you by Interface Builder are only a best guess, so sometimes you need to add your own constraints or modify an existing constraint to get the exact resizing and repositioning you need for the controls in your App.
When you manually add a new constraint or modify an existing constraint, it creates something called a user constraint. Let’s give it a try.
Figure 8.32 The Width constraint
You can also see the constraint in the Document Outline pane listed under the button (Figure 8.33). Constraints that are specific to a single control are listed directly under the control.
Figure 8.33 Width constraint in the Document Outline pane
Figure 8.34 The width constraint attributes
Notice there is no Standard option as there was with the spacing constraints, just aConstant setting that specifies the width of the object in points. This indicates the button will always be 73 points wide.
That might be OK if the text of the button always stays the same, but if the text of the button changes at run time (as it does if your App supports multiple languages), this hard-coded setting won’t work well.
To see what I mean, let’s connect the button to an outlet that’s already been created for you. To do this, first display the Assistant Editor (in Xcode’s toolbar, click the center button in the Editor button set). This should display the ViewController.h file in the Assistant Editor (if it doesn’t, select the file in the Assistant Editor’s jump bar).
Figure 8.35 Connect the button to the btnTest outlet.
[self.btnTest setTitle:@"Completed!"
forState:UIControlStateNormal];
Figure 8.36 The button title is clipped.
That’s because the constraint told the button that it could only be 73 points wide—not wide enough to display the complete title.There are a few ways you can fix this problem. To start, let’s modify the constraint to allow the button to increase in width as its content changes.
Figure 8.37 Set the Relation to Greater Than or Equal.
Changing this default constraint created by Interface Builder changes the automatic constraint to a user constraint. Notice it’s color has changed from purple to blue in the Document Outline pane (Figure 8.38). In addition, the “I” constraint bar in the view is bolded. These are great visual cues so you can easily identify which user constraints you have changed or manually added.
Figure 8.38 Width is now a user constraint.
Figure 8.39 The button title is no longer clipped!
Usually, it’s best to let a button decide its size rather than hard-coding a constraint that sets its size to a hard-coded value.
In this set of steps, I wanted to show you how to change the Relation attribute of a constraint to allow it to expand to its intrinsic size. Ultimately, there is even a better way to do this.
In the previous section, you saw that, at times, Interface Builder adds unnecessary constraints to your view. Since you want to keep your views as simple as possible, you should only have the constraints you absolutely need. In the next set of steps you will add a label to the view and learn how to avoid some of these unnecessary constraints.
Figure 8.40 Drop a label in the top center of the scene.
Just as you would expect, this adds Center X Alignment and Vertical Spaceconstraints for the label (Figure 8.41). If you look closely, you can see that the label is center aligned to the button rather than the view (the text Label - Label - Button - Done indicates the Label named Label is aligned to the Button named Done. This is standard behavior when you are centering multiple controls in the same view.
Figure 8.41 The new label constraints
Notice this adds a width constraint as shown in the design surface (Figure 8.42) and clips the label text.
Figure 8.42 The label’s width constraint
As you learned in the previous section, width constraints created in this way are usually not desirable. I’ll show you an easy way to get rid of them.
The lesson to take away from this is that you should set a label’s text by double-clicking in the design surface rather than setting it in the Attributes Inspector. Note that this trick works with other controls that have a Text attribute such as buttons and segmented controls.
In Part 3 of this tutorial, we'll take the lessons on Auto Layout even further!
Kevin McNeish
Author: iOS App Development for Non-Programmers book series
Twitter: @kjmcneish