New in this month’s release of Reveal is support for Auto Layout guides. Represented by the
UILayoutGuide class, layout guides have been introduced to UIKit as an efficient replacement for “dummy views”, and can be used as spacing between views or to help implement a complex layout. Built-in views like
UILayoutGuide internally to implement their layout behavior, while several UIKit classes expose special guides to allow access to specific layout features.
UILayoutGuide defines a rectangular area inside its owning view which interacts with Auto Layout, but does not provide any content. You can create layout guides manually to implement advanced constraint configurations: for example, creating equal or proportional spacing between views.
UIStackView provides similar functionality (and it’s implemented using layout guides too), but it’s great to have an efficient tool for implementing such layout manually.
UIKit also provides focus guides (
UIFocusGuide). These can be used on tvOS to define an invisible area that redirects focus to some other view. And because they inherit all properties of layout guides, they participate in Auto Layout in the same way.
In addition to supporting custom layout guides, UIKit also provides several “standard” guides:
UIView.layoutMarginsGuide: a portion of the view’s bounds inside its layout margins.
UIView.readableContentGuide: an area of the view which has width optimized for reading text without moving one’s head.
UIViewController.bottomLayoutGuide: define the highest and the lowest visible extents of the view controller’s view. These are not always represented by
UIImageView.focusedFrameGuide(tvOS only): represents the visible frame of an image view when it’s focused.
In Reveal, layout guides appear in the Outline view, the Inspectors, and the Canvas – just like views and constraints.
In the Outline, layout guides owned by a view are inside that view’s “Layout Guides” group. In the Canvas, layout guides are visualized as wireframes with their own unique color. Note that layout guides are rendered “hollow” in the Canvas: this reflects the fact that they don’t render any content themselves. To select a layout guide in the Canvas, click on its wireframe.
Just like views, layout guides in Reveal support features such as:
- Participating constraints in the Layout inspector,
- Layout ambiguity warnings,
- Advanced view hierarchy filtering (by identifier and class name).
And just like constraints, layout guides can be hidden from the Outline view and the Canvas using the “Constraints and Guides” toggle in the bottom-left corner of the Canvas.
Being able to inspect layout guides is useful when debugging issues in views like
UIStackView which use
UILayoutGuide to implement their internal layout. For example, if a constraint attached to a layout guide gets broken by Auto Layout, inspecting your app in Reveal will highlight that constraint with a layout error, and now, Reveal will also show which layout guide the constraint is related to, and visualize it in the Canvas.
Even if you don’t have any layout issues, having the information about all layout participants gives you an insight into how the layout is implemented in system-provided views. On tvOS, this also has the added benefit of being able to see the invisible focus guides that you or the system have created – and to check that their size and position match your expectations.
You can find an example of using layout guides and focus guides – and see how Reveal visualizes them – on the new “Auto Layout Guides” page of the Revert project.
The curious case of view controllers’ guides
As mentioned above,
UIViewController provides two built-in layout guides:
bottomLayoutGuide. However, these are not always
UILayoutGuide appeared in iOS 9, top/bottom layout guides API was introduced back in iOS 7. Thus, the underlying implementation of these guides in iOS 7 and 8 always used hidden views with a private class
_UILayoutGuide (note the underscore). I wouldn’t be surprised to learn that
UILayoutGuide were already in the plans during that time frame, because both these properties are exposed using a special
UILayoutSupport protocol instead of having an explicit class. This was a convenient foresight, as it may have allowed UIKit engineers to seamlessly replace the implementation without changing the API.
Even in iOS 9 and 10, the situation is still complicated. When inspecting your apps, you may find that in some cases top and bottom layout guides are now actual layout guides (represented by a private class
_UILayoutSpacer), whereas in other situations they are still
_UILayoutGuide views. For example, view controllers decoded from a storyboard tend to use view-based implementation, while those instantiated and embedded manually usually have
_UILayoutSpacer as their top and bottom layout guides.
_UILayoutGuide objects show up among views, but have the same icon and Canvas color as layout guides. This reflects the duality of these objects: technically, they are views (and are listed as their owners’ subviews), but conceptually, they are used as guides.
Fortunately, as API users we don’t usually have to worry about this difference: UIKit takes care of hiding this abstraction from us. But it is still important to keep in mind, as per The Law of Leaky Abstractions, all non-trivial abstractions, to some degree, are leaky. And when problems (like layout issues) occur, the more you know about the abstraction, the better. So next time you’re wondering how view controllers in your app implement their layout guides, just inspect it in Reveal!