An Introduction to Auto Layout in iOS 7

From Techotopia
Jump to: navigation, search
PreviousTable of ContentsNext
Writing iOS 7 Code to Hide the KeyboardWorking with iOS 7 Auto Layout Constraints in Interface Builder


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


Arguably one of the most important parts of designing the user interface for an application involves getting the layout correct. In an ideal world, designing a layout would simply consist of dragging view objects to the desired location on the screen and fixing them at these positions using absolute X and Y screen coordinates. In reality, the world of iOS devices is more complex than that and a layout must be able to adapt to variables such the device rotating between portrait and landscape modes, dynamic changes to content and differences in screen resolution and size.

Prior to the release of iOS 6, layout handling involved use of a concept referred to as autosizing. Autosizing involves the use of a series of “springs” and “struts” to define, on a view by view basis, how a subview will be resized and positioned relative to the superview in which it is contained. Limitations of autosizing, however, typically meant that considerable amounts of coding were required to augment the autosizing in response to orientation or other changes.

Perhaps one of the most significant new features in iOS 6 was the introduction of Auto Layout, which has continued to evolve with the release of iOS 7. Auto Layout is an extremely large subject area allowing layouts of just about any level of flexibility and complexity to be created once the necessary skills have been learned.

The goal of this and subsequent chapters will be to introduce the basic concepts of Auto Layout, work through some demonstrative examples and provide a basis on which to continue learning about Auto Layout as your application design needs evolve. Auto layout introduces a lot of new concepts and can, initially, seem a little overwhelming. By the end of this sequence of chapters, however, it should be clearer how the pieces fit together to provide a powerful and flexible layout management system for iOS based user interfaces.


Contents


An Overview of Auto Layout

The purpose of Auto Layout is to allow the developer to describe the behavior that is required from the views in a layout independent of the device screen size and orientation. This behavior is implemented through the creation of constraints on the views that comprise a user interface screen. A button view, for example, might have a constraint that tells the system that it is to be positioned in the horizontal center of its superview. A second constraint might also declare that the bottom edge of the button should be positioned a fixed distance from the bottom edge of the superview. Having set these constraints, no matter what happens to the superview, the button will always be centered horizontally and a fixed distance from the bottom edge.

Unlike autosizing, auto layout allows constraints to be declared not just between a subview and superview, but between subviews. Auto layout, for example, would allow a constraint to be configured such that two button views are always positioned a specific distance apart from each other regardless of changes in size and orientation of the superview. Constraints can also be configured to cross superview boundaries to allow, for example, two views with different superviews (though in the same screen) to be aligned. This is a concept referred to as cross-view hierarchy constraints.

Constraints can also be explicit or variable (otherwise referred to in auto layout terminology as equal or unequal). Take for example, a width constraint on a label object. An explicit constraint could be declared to fix the width of the label at 70 points. This might be represented as a constraint equation that reads as follows:

myLabel.width = 70

This explicit width setting might, however, become problematic if the label is required to display dynamic content. An attempt to display text on the label that requires a greater width will result in the content being clipped.

Constraints can, however, also be declared using less-than or equal to or greater than or equal to controls. For example the width of a label could be constrained to any width as long as it is less than or equal to 800:

myLabel.width <= 800

The label is now permitted to grow in width up to the specified limit, allowing longer content to be displayed without clipping.

Auto layout constraints are by nature interdependent and, as such, situations can arise where a constraint on one view competes with a constraint on another view to which it is connected. In such situations it may be necessary to make one constraint stronger and the other weaker in order to provide the system with a way of arriving at a layout solution. This is achieved by assigning priorities to constraints.

Priorities are assigned on a scale of 0 to 1000 with 1000 representing a required constraint and lower numbers equating to optional constraints. When faced with a decision between the needs of a required constraint and an optional constraint, the system will meet the needs of the required constraint exactly while attempting to get as close as possible to those of the optional constraint. In the case of two optional constraints, the needs of the constraint with the higher priority will be addressed before those of the lower.

Alignment Rects

When working with constraints it is important to be aware that constraints operate on the content of a view, not the frame in which a view is displayed. This content is referred to as the alignment rect of the view. Alignment constraints such as those that cause the center of one view to align with that of another will do so based on the alignment rects of the views, disregarding any padding that may have been configured for the frame of the view.


Intrinsic Content Size

Some views also have what is known as an intrinsic content size. This is the preferred size that a view itself believes it needs to be to display its content to the user. A Button view, for example, will have an intrinsic content size in terms of height and width that is based primarily on the text or image it is required to display and internal rules on the margins that should be placed around that content. When a view has an intrinsic content size, auto layout will automatically assign two constraints for each dimension for which the view has indicated an intrinsic content size preference (i.e. height and/or width). One constraint is intended to prevent the size of the view becoming larger than the size of the content (otherwise known as the content hugging constraint). The other constraint is intended to prevent the view from being sized smaller than the content (referred to as the compression resistance constraint).

Content Hugging and Compression Resistance Priorities

The resize behavior of a view with an intrinsic content size can be controlled by specifying compression resistance and content hugging priorities. A view with a high compression resistance priority and a low content hugging priority will be allowed to grow but will resist shrinking in the corresponding dimension. Similarly, a high compression resistance priority in conjunction with a high content hugging priority will cause the view to resist any form of resizing, keeping the view as close as possible to its intrinsic content size.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Three Ways to Create Constraints

There are three ways in which constraints in a user interface layout can be created:

  • Interface Builder – The latest release of Interface Builder has been modified extensively to provide support for the visual implementation of auto layout constraints in user interface designs. Examples of using this approach are covered in the Working with iOS 7 Auto Layout Constraints in Interface Builder and An iOS 7 Auto Layout Example chapters of this book.
  • Visual Format Language – The visual format language defines a syntax that allows constraints to be declared using a sequence of ASCII characters that visually approximate the nature of the constraint being created with the objective of making constraints in code both easier to write and understand. Use of the visual format language is documented in the chapter entitled Understanding the iOS 7 Auto Layout Visual Format Language.
  • Writing API code – This approach involves directly writing code to create constraints using the standard programming API calls, the topic of this is covered in Implementing iOS 7 Auto Layout Constraints in Code.

Wherever possible, Interface Builder is the recommended approach to creating constraints. When creating constraints in code, the visual format language is generally recommended over the API based approach.

Constraints in more Detail

A constraint is created as an instance of the NSLayoutConstraint class which, having been created, is then added to a view. The rules for a constraint can generally be represented as an equation, the most complex form of which can be described as follows:

view1.attribute = multiplier * view2.attribute2 + constant

In the above equation, a constraint relationship is being established between two views named view1 and view2 respectively. In each case an attribute is being targeted by the constraint. Attributes are represented by NSLayoutAttribute<name> constants where <name> is one of either Left, Right, Top, Bottom, Leading, Trailing, Width, Height, CenterX, CenterY or Baseline (i.e. NSLayoutAttributeWidth). The multiplier and constant elements are floating point values used to modify the constraint.

A simple constraint that dictates that view1 and view2 should, for example, be the same width would be represented using the following equation:

view1.width = view2.width

Similarly, the equation for a constraint to align the horizontal center of view1 with the horizontal center of view 2 would read as follows:

view1.centerX = view2.centerX

A slightly more complex constraint to position view1 so that its bottom edge is positioned a distance of 20 points above the bottom edge of view2 would be expressed as follows:

view1.bottom = view2.bottom – 20

The following constraint equation specifies that view1 is to be twice the width of view2 minus a width of 30 points:

view1.width = view2.width * 2 - 30

So far the examples have focused on equality. As previously discussed, constraints also support inequality in the form of <= and >= operators. For example:

view1.width >= 100

A constraint based on the above equation would limit the width of view1 to any value greater than or equal to 100.

The reason for representing constraints in the form of equations is less obvious when working with constraints within Interface Builder but will become invaluable when setting constraints in code either using the API or the visual format language.

Summary

Auto layout involves the use of constraints to descriptively express the geometric properties, behavior and relationships of views in a user interface.

Constraints can be created using Interface Builder, or in code using either the new visual format language or the standard SDK API calls of the new NSLayoutConstraint class.

Constraints are typically expressed using a linear equation, an understanding of which will be particularly beneficial when working with constraints in code.

Having covered the basic concepts of auto layout, the next chapter will introduce the creation and management of constraints within Interface Builder.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
Writing iOS 7 Code to Hide the KeyboardWorking with iOS 7 Auto Layout Constraints in Interface Builder