In OS X Lion and iOS 6 Apple added a new way to layout views, Auto Layout. This is a very powerful system that will handle a lot of
the work and overhead of arranging your views. A well defined layout can make many headaches disapear entirely. However, it is a bit…quirky…to say the least.[^1]
I recommend that you read the guide to the visual format language before going on.
This post will discuss the various options that you can set in
[constraintsWithVisualFormat:options:metrics:views:
][]. These options affect how the views described in the format string are to be aligned with each other.
Throughout this post, we’ll be discussing code from a sample project I’ve
created, called AutoLayoutAlignment, available in github.
What Options Do
In the constraintsWithVisualFormat:options:metrics:views:
, the options
parameter is a bitmask that allows you define how the views in the format
string are aligned with each other. For example, the string
@"V:[first][second][third]"
, only tells you that the three views should be vertically stacked. It does not say what to do if the views are of different widths.
You could handle this by putting in a horizontal set of constraints for each
view, but this would become quickly tedious. Instead you can pass in an option to tell the layout engine how to poistion them relative to each other.
The Options
There are three sets of options: ones that apply to vertical constraints, ones
that apply to horizontal constraints and ones that adjust the direction
horizontal constraints apply. They are all part of [NSLayoutFormatOptions
][]
Vertical Constraint Options
NSLayoutFormatAlignAllLeft
– This aligns all of the views on their left edge.NSLayoutFormatAlignAllRight
– This aligns all of the views on their right edge.NSLayoutFormatAlignAllLeading
– This aligns all of the views on the edge that is the start of text in the current locale (English: left, Hebrew: right).NSLayoutFormatAlignAllTrailing
– This aligns all of the views on the edge that is the end of text in the current locale (English: right, Hebrew: left).NSLayoutFormatAlignAllCenterX
– This aligns all of the views by setting their center’s X value equal to each other.
Of particular note is the leading and trailing alignments. Generally speaking
you probably want to use these instead of left and right, to allow your UI to
adjust for languages that read in the opposite direction than yours.
Horizontal Constraint Options
NSLayoutFormatAlignAllTop
– This aligns all of the views on their top edge.NSLayoutFormatAlignAllBottom
– This aligns all of the views on their bottom edge.NSLayoutFormatAlignAllCenterY
– This aligns all of the views by settings their center’s Y value equal to each other.NSLayoutFormatAlignAllBaseline
– This lines up the views according to their baseline, which for text based views is the bottom of text that does not drop down (like g, p, j, etc). For non-text views it is the same as the bottom edge. When lining up text with each other it tends to look visually appealing to
align on the baseline, but may not be what you want with a mixed set of views.
Direction Constraint Options
These can be or’d (|
) into another option you pick for horizontal constraints.
NSLayoutFormatDirectionLeadingToTrailing
– The format string is read in assuming that the leading view in the string should be on the leading side of the display. Once again, based on the locale in use.NSLayoutFormatDirectionLeftToRight
– The format string is read in assuming that the leading view in the string should be on the left side of the display.NSLayoutFormatDirectionRightToLeft
– The format string is read in assuming that the leading view in the string should be on the right side of the display.
The default is NSLayoutFormatDirectionLeadingToTrailing
and is generally what you want to use.
How They Apply
Go ahead and launch the example app, and you’ll quickly see how these alignment options work.
At the bottom center are the visual format strings being used in the two large
views on screen. The alignment settings are defined in the popover presented from the bottom left button. Try adjusting the settings for the alignment options, you should notice the text labels moving around their parent views, and hopefully see just how these work.
There is an additional setting in the app that is not an
NSLayoutFormatOptions
item. The “Apply Option to Superview as Well” setting adds an additional constraint to these views. It applies a constraint that connects the top or leading view to the superview using the equivalent
[NSLayoutAttribute
][] by using
[constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:
].
It is important to note how the views cease to move around if you disable the
superview connecting constraint. Even though the superview is reference in the format string as |
, the reference is only used for positioning purposes, and alignment options do not apply. If you do not set up the alignment to the
superview, the layout is considered ambiguous and the layout engine can’t
perfectly apply it. We’ll discuss later what ambiguity is, and how to fix it.
For now, take note that there is a button that will log to the console the
trace that will show what views on screen are ambiguous.
Conclusion
Hopefully you now understand what the options
argument is for, and how you can use it to align views when defining them in the visual format string.
Please send questions my way, either via email (spr (at) iosdevelopmentjournal (dot) com) or on twitter/app.net at _spr_.
Keep an eye out for future auto layout posts that will cover issues like
multi-line labels, creating sufficient layouts, and handling dynamic view
creation.
[^1]: I will not be tackling interface builder’s use of auto layout. I do not use interface builder heavily, and its quirks are a whole different story.