In the last blog post I explained several techniques for debugging Auto Layout issues using the storyboards in development mode and the Xcode console at runtime.
Each of these techniques has its limitations:
- the storyboards are rarely used to entirely define the UI , especially when the view hierarchy starts to become a bit complex. Views or constraints are often added or removed dynamically, in code. The layout error detection features in Interface Builder only work in development mode and aren’t of much use for the components created at runtime.
- the console shows Auto Layout errors and warnings and there even exists some private API to display textually the view hierarchy. But it’s hard to map the memory addresses of UIView and NSLayoutConstraint instances from the console with the views displayed on screen.
Apple introduced in Xcode 6 a runtime debugging feature that shows the complete view hierarchy as it is displayed on screen. Each view and constraint that is part of the current screen is presented inside a browsable structure and its layout properties can be inspected. This tool can be very helpful in to analyze layout issues (misplaced or wrongly sized views, missing or incorrect constraints) or simply to check that the results of the layout process are correct.
To display the view debugger in Xcode, run the application, display the screen that you want to analyze, go to the Debug menu and click on View Debugging / Capture View Hierarchy. Alternatively, you can click on the Debug View Hierarchy button in the Debug Area command bar:
The app execution is suspended as for a breakpoint set in code and the view hierarchy debugger is displayed in Xcode. To resume the execution, click on the Continue program execution button:
View hierarchy inspector tools
The Xcode debugger window displays the front view of the current screen content. It draws a light grey border around the frame of each visible subview. Notice in the following screenshot that the table view height extends below the tab bar, suggesting that there may be hidden content which can be revealed by scrolling:
The border around the view frames is called wireframe. It can be displayed or not, depending on the selected option from the Adjust the view mode list:
Some views in the hierarchy are stacked behind other views, which makes them invisible on screen. By clicking anywhere on the view debugger screen and dragging in any direction, the entire view hierarchy, from the root window to the top most view, is displayed in perspective as a 3D stack. Any view from the stack can be selected and useful information about it is displayed in the Object inspector and Size inspector on the right. The view hierarchy is also displayed in the Debug navigator on the left, making it easier to identify and select a specific view.
The views at the bottom of the stack are system generated and the developer has very little control over them. To declutter the view hierarchy and focus on the custom views of the app, use the filtering slider on the right side of the view debugger. By dragging the left handle, the views from the bottom of the stack are progressively hidden. The same thing happens to the views from the top of the stack if the right handle is dragged to the left.
After filtering the less interesting views from the hierarchy, increase the spacing between the remaining views using the slider on the left side of the view debugger:
For a detailed inspection of a specific subview, zoom in on it using the + button from the view debugger tool bar. The = button resets the zooming level to default:
To go back to the two-dimensional front view of the hierarchy, use the Reset the viewing area button.
In addition to views, the debugger also gives access to Auto Layout constraints. They are displayed in the Debug navigator on the left, or directly in the view debugger when the Show constraints option is selected. This feature is very useful when you want to check the runtime constraints are set exactly how they’re expected. Notice in the screenshot below that some constraints were automatically created at runtime by the Auto Layout system in addition to the custom constraints created in code or Interface Builder. They were necessary to fully determine each view’s frame and generate the layout.
The last feature available in the view debugger toolbar is Show clipped content. It displays the full content of the views that have the clipsToBounds property set to YES.
This was an overview of one of the most interesting features introduced in Xcode 6, the view hierarchy debugger. Inspecting the views frames and constraints at runtime is very useful when tracking down rendering and layout issues; it saves a lot of time compared to the classic logging based debugging methods.
In its current version, the view debugger misses some features like live view and constraint property modifications. If you are looking for a more advanced view hierarchy inspection tool, I recommend Reveal, which is a few steps ahead in terms of features and usability.