View Debugging in Xcode 6
In this tutorial, you will learn view debugging by using some of the awesome new tools provided with Xcode 6! By Scott Berrevoets.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
View Debugging in Xcode 6
30 mins
Old School Debugging
Live view debugging made debugging views in Xcode 6 a lot easier, but that doesn’t mean that your favorite old school tricks are now useless. In fact, iOS 8 introduces a very welcome addition to the family of view debugging tricks: _printHierarchy
.
Printing the View Controller Hierarchy
_printHierarchy
is a private method on UIViewController
that you can use to print the view controller hierarchy to the console. Build and Run, select Push via storyboard and then hit the pause button in the Debug bar.
Now type this in the console and press return:
po [[[[UIApplication sharedApplication] keyWindow] rootViewController] _printHierarchy]
You’ll get something very similar to this:
<UINavigationController 0x7fdf539216c0>, state: appeared, view: <UILayoutContainerView 0x7fdf51e33bc0> | <TableViewController 0x7fdf53921f10>, state: disappeared, view: <UITableView 0x7fdf5283fc00> not in the window | <DemoMessagesViewController 0x7fdf51d7d520>, state: appeared, view: <UIView 0x7fdf53c0b990>
This tells you that there is a UINavigationController
whose first view controller is a TableViewController
— the one where you chose how to push the controller. The second view controller is the DemoMessagesViewController
, or the view controller you have been debugging.
It doesn’t seem too exciting in this particular example, but if you have several child view controllers within a navigation controller, and a tab bar controller in a popover in a modal view controller, (I’m not proud of some of my apps’ UI…) it can be immensely useful for figuring out exactly how the view controller hierarchy works.
Printing the View Hierarchy
If you’re not a very visual person and prefer a textual overview of a view hierarchy, you can always use the age-old, and also private, recursiveDescription
on UIView
. This prints a view hierarchy very similar to the view controller hierarchy as demonstrated above.
Open Views\JSQMessagesCollectionViewCellOutgoing.m and add a breakpoint in awakeFromNib
.
Build and Run, then select Push via Storyboard. The debugger should break as a JSQMessagesCollectionViewCellOutgoing
is loaded. Now type the following into the console:
po [self.contentView recursiveDescription]
This will print the hierarchy of the JSQMessagesCollectionViewCellOutgoing
’s contentView
, which will look something like this:
<UIView: 0x7fde6c475de0; frame = (0 0; 312 170); gestureRecognizers = <NSArray: 0x7fde6c484fe0>; layer = <CALayer: 0x7fde6c474750>> | <JSQMessagesLabel: 0x7fde6c475eb0; baseClass = UILabel; frame = (0 0; 312 20); text = 'Today 10:58 PM'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c476030>> | <JSQMessagesLabel: 0x7fde6c476400; baseClass = UILabel; frame = (0 20; 312 0); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c476580>> | <UIView: 0x7fde6c476b50; frame = (70 20; 210 150); autoresize = RM+BM; layer = <CALayer: 0x7fde6c474dd0>> | | <UIImageView: 0x7fde6c482880; frame = (0 0; 210 150); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7fde6c476ae0>> - (null) | <UIView: 0x7fde6c482da0; frame = (282 140; 30 30); autoresize = RM+BM; layer = <CALayer: 0x7fde6c482d00>> | | <UIImageView: 0x7fde6c482e70; frame = (0 0; 30 30); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7fde6c482f70>> - (null) | <JSQMessagesLabel: 0x7fde6c483390; baseClass = UILabel; frame = (0 170; 312 0); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c483510>>
It’s rudimentary, but can be helpful when you want to debug a view hierarchy pre iOS 8.
Using debugQuickLookObject
Lastly, Xcode 5.1 introduced a feature called Debug Quick Look. This feature is most useful when you’re already debugging and aren’t wondering what an object looks like at a certain point in your code.
Your custom class can implement the method debugQuickLookObject
and return anything that is visually presentable by Xcode. Then, when you’re debugging and you have an object you want to inspect, you can use quick look and Xcode will show you a visual representation of that object.
For example, NSURL
’s implementation of debugQuickLookObject
returns a UIWebView
with that URL so you can actually see what’s behind the URL.
For more information on debugging using Quick Look, take a look at the documentation.
Where To Go From Here?
And that’s it for Live View Debugging. It’s an easy tool and can save hours of manually sifting through a view hierarchy trying to understand how and where it’s drawing views.
If you’re looking for a more advanced and comprehensive tool than just Xcode, then take a look at Reveal. While it’s a paid app, it’s also more powerful than Xcode’s view debugging. You can view our Tech Talk on the subject over here.
We hope you enjoyed this tutorial and feel a little more comfortable debugging your UI. If you have comments or questions, please use the forum discussion below!