The most important design feature in iOS 6 has to be Auto Layout, which is a way to manage the sizing and positioning of your controls in your user interface. Auto Layout improves over Springs and Struts which provided similar functionality but were not nearly as robust or complete.
Here are some of the features of Auto Layout that can help you create better interfaces:
Constraints represent relationships between user interface elements giving you the ability to not only layout your user interface but also describing its intent. You can articulate relationships like “these two views should be the same size” or “this label and button should always stick together”. This is a really powerful way to design your UI because it reacts to the orientation and size of the device.
A constraint is simply an equation:
item1.attribute1 = item2.attribute2 x multiplier + constant
This equation is merely a visual understanding of the actual API call to the class
NSLayoutConstraint. Here is a diagram of how the equation maps to the method call:
You either define a constraint using Interface Builder or in code using the class
NSLayoutConstraint. Constraints are not directional which means that the layout is neither top down or bottom up. However, constraints do have priorities which means constraints with higher priorites are satisified before constraints with lower priority.
ASCII-Art Based Constraints
If you want to use constraints programmatically and are weary of API calls due to the complexity of your constraint then fear not, you can represent your constraint using ASCII-Art. Confused? Don’t be. You already know what your constraint should look like so why not draw it out using characters?
Once again you define a constrain on the instance of
NSLayoutConstraint and this time call the method
constraintsWithVisualFormat:options:metrics:views:, where the visual format parameter is a string based on “Visual Format Language”
Let’s explore a simple example of two buttons within a container view. Both buttons are flushed to either side of the container view as shown belown:
We define a visual format constraint which says we want the two buttons at a standard distance from each other. A hyphen denotes a standard Aqua space, which is usually 8 points.
This results in one button becoming larger than the other.
To equally size both the buttons we could define the string as follows:
The result is as expected where both the buttons are equal in size.
What if we wanted to have some space between the edges of the container and buttons? That can be easily defined too:
Resulting in neatly aligned and sized buttons.
For more information be sure to check out Apple’s documentation on the “Visual Format Language”.
As for the code, this is how you would use the above language:
01 NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(cancelButton, acceptButton); 02 03 NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"|-[cancelButton]-[acceptButton(==cancelButton)]-|" 04 options:0 05 metrics:nil 06 views:viewsDictionary]; 07 [self.view addConstraints:constraints];
The first line creates a dictionary of all your controls with help of
NSDictionaryOfVariableBindings macro. In the next line you create an array of constraints in case you have multiple constraints to be defined. And finally, you assign the constraints array to a view that contains the view hierarchy of all your controls defined in the dictionary.
Intrinsic Content Size
Creating complex views involves writing numerous lines of tedious code calculating the given geometry of the views and laying them out manually. This produces code that is difficult to maintain and increases the complexity of the controller logic, let alone allowing for a redesign. The Auto Layout architecture distributes responsibility for the layout between controllers and views. One such way is having controls define their Intrinsic Content Size.
UIView defines a method called
intrinsicContentSize which by default does not do anything. However, views such as buttons typically know more about what size they should be than does the code that is positioning them. The layout system calls the method
intrinsicContentSize when trying to size and position controls such as buttons, labels, textareas, etc. The layout system has no idea about the size of the content within these controls and hence needs to be instructed about their intrinsic size.
The layout system calls intrinsicContentSize, and will set up constraints that specify
1. Content Compression: whether content should be compressed or clipped
2. Content Hugging: a view prefers to hug tightly to its content.
A view can implement intrinsicContentSize to return absolute values for its width and height, or
NSViewNoInstrinsicMetric for either or both to indicate that it has no intrinsic metric for a given dimension.
The intrinsic size for a text button is dictated by its title text. A button’s
intrinsicContentSize method should return a size with width and height that will ensure that the title text is not clipped.
Designing for an iOS device is more complex than ever given the various devices, resolutions and orientation. However, thanks to Auto Layouts a huge paradigm shift has occured. You can now have layouts that are responsive and maintainable.