The Ultimate Guide to UILayoutGuide
Creating a desired layout using Autolayouts is like a puzzle to solve. And dummy views are an important elements to the solution. There are instances where you cannot only rely on constraints. For Example you have three buttons which you want to be equally spaced. There isn’t any type of constraint that will allow you to do that. As a trick you use dummy views between the button and assign all the dummy views the equal width constraint. So whenever there is a change in the layout the dummy views will adjust accordingly keeping their width equal, hence separating the buttons with the similar spacing.
Another use of dummy views is to group several controls together and then aligning the dummy view with external view. In this image below, buttons are grouped in a view which in turn is then centered in the superview.
There is nothing wrong with using dummy views wherever required. The only problem is that a dummy view is just like a normal view. It is added in the view hierarchy and takes part in the layout process. Even if it’s invisible, UIKit’s layout engine treats it just like a normal view and performs all the work that’s being done on a normal view. This becomes a performance hit if you are using a lot of dummy views in a single view.
UILayoutGuide
To solve this problem Apple introduced UILayoutGuide API in iOS 9. UILayoutGuide is designed to performs all the tasks that dummy views were used for previously. Just like a view, UILayoutGuide objects are added in a view. UILayoutGuide defines a rectangular area in its parent view’s coordinat system. Multiple instances of UILayoutGuide can be added to a view. Unlike a dummy view, a layout guide instance is not rendered on screen, hence it doesn’t take part in the view hierarchy.
Example 1: Adding a space b/w two views via UILayoutGuide
This example demonstrates the use of UILayoutGuide. The result achieved in this example can also be achieved by only adding appropriate constraints.
Top and Bottom layout guides:
To dynamically adjust your subviews UIViewController provides topLayoutGuide and bottomLayoutGuide properties. Top layout guide changes depending upon the visibility of status bar and navigation bar on the screen. Similarly bottom layout guide changes depending upon the visibility of tab bar.
By anchoring your subviews from these top and bottom layout guides provided by a viewcontroller you enable your user interface to dynamically adapt according to the changing top and bottom layouts.
As you can see in the examples above, a view pinned with top or bottom layout guide adjusts itself dynamically with visibility of top and bottom bars.
Navigation bar changes its height in landscape orientation and also changes its height when the phone is in a call, using layout guides covers a lot of edge cases and prevents your UI to be obscured from ever changing top and bottom bars.
Top and bottom layout guides are not UILayoutGuide objects. Instead they are properties defined on UIViewController that confirms to UILayoutSupport protocol. UILayoutSupport protocol provides properties that can be used in NSLayoutConstraint and NSLayoutAnchor APIs to align your views with the top or bottom of a view controller. These properties are:
(Note: Check this detailed article of mine about NSLayoutAnchor API.)
- length
- topAnchor
- bottomAnchor
- heightAnchor
length of top layout guide depends upon the status bar and navigation bar visibility. If both status bar and navigation bar are visible then the length is 64 pixels (20 + 44) in portrait mode and 52 pixels(20 + 32) in landscape mode. If navigation bar is hidden it is 20 pixels. And if both are hidden then its zero.
Similarly length of bottom layout guide depends upon the visibility of tab bar. If its visible, length is 49 pixels in both landscape and portrait. If it is hidden the length is zero.
topAnchor represents the top surface of the rectangular guide while bottomAnchor represents the lower part.
Pinning Your views with top/bottom layout guides
To pin your view with top/bottom layout guide in InterfaceBuilder:
- Select your view.
- Select ‘Add New Constraints’ option in the InterfaceBuilder.
- From the dropdown menu of top or bottom constraint, select the ‘Top Layout Guide’ or ‘Bottom Layout Guide’.
To pin your views programmatically:
There is a little trick in pinning your view to the top and bottom layout guides programmatically. For pinning a view with the top, you pin the top anchor of your view with the bottom anchor of the top layout guide. Similarly for pinning a view with the bottom, you pin it with the top anchor of the bottom layout guide.
Example 2: Grouping multiple views
This example shows how you can group multiple related views together using UILayoutGuide.
Note: Onc caveat here is that if you are grouping your views using a UIView you have the luxury to hide the grouped controls at once by hiding the parent view. UILayoutGuide doesn’t provide that option since it is just a rectangular area.
Debugging the UILayoutGuide
Layout guides can be viewed in Debug View Hierarchy window of the Xcode. Xcode not only shows the UILayoutGuide instances added in a view, it also displays their frames and applied constraints upon selecting a particular instance.
To make things more visible you can add a CALayer object with the same frame as of UILayoutGuide’s instance. UILayoutGuide’s layoutFrame property returns the frame in the coordinate system of its owning view. This property is only valid once -layoutSubviews method is called on the owning view. A better place for using this is ‘viewDidLayoutSubviews()’ method of the UIViewController.
Following image shows the layoutMarginsGuide’s frame of the view.
Example 3: Equally spaced views
This example snippet demonstrates how UILayoutGuides can be used to create equally spaced views.
Conclusion
As we saw in this article, UILayoutGuide is a handy API that Apple introduced. It not only gives us the flexibility to add constraints easily but also does that in an efficient way, without adding extra work on the UIKit rendering engine.
Call To Action
If you enjoyed this little piece of mine, do hit the clap button below. I wrote a similar piece about LayoutAnchors API, check that too.