Tip: Ambiguous Auto Layouts in iOS 6
In the last tip on Auto Layout in iOS 6, we looked at how to debug unsatisfiable constraints. Ambiguous constraints are equally problematic, but they are more subtle.
Once you’ve set satisfiable constraints on your iOS 6 views, they may not be sufficient to define the look you want. Fundamentally, ambiguous layouts occur when multiple potential layouts can satisfy the constraints you’ve set. If you’re lucky, you have an epiphany when you see that your poorly-specified layout has problems. If not, it’s debugging time.
Missing views are a common symptom of using the ambiguous layout. A view that you expect to see simply isn’t visible, often because it has a zero width or zero height. This often happens if you only specify constraints in one dimension.
In order for a layout to be unambiguous, each view needs four pieces of information: how wide it should be, how high it should be, where it should be in X coordinates, and where it should be in Y coordinates. If you don’t constrain one of these attributes, especially the width and height, you’ll often get missing views.
Take a look at Erica Sadun’s digital short, titled Introducing View Constraints: The Core iOS 6 Developer’s Cookbook for more on creating relations between on-screen objects to specify the way iOS 6 automatically arranges your views.
Debugging overlapping views
Once your views are visible, they may overlap or intrude on one another’s space. For example, this happens if you omit the character from the format specifiers in your tab demo (see the tip on Manually Adding iOS 6 Auto Layout Constraints) that pins the last tab to the right edge. In this case, you get overlapping tabs:
It’s fairly obvious that the layout is ambiguous from the screenshot, but we can verify this using the debugger. If you pause execution, you can type this into lldb:
po [[UIWindow keyWindow] _autolayoutTrace]
Doing so in our example leads to this output:
(id) $2 = 0x07660200 *<UIWindow:0x718d7f0> | *<UIView:0x7190730> | | *<UIView:0x718ff70> | | | *<UIView:0x7191be0> - AMBIGUOUS LAYOUT | | | | *<UILabel:0x7192160> - AMBIGUOUS LAYOUT | | | *<UIView:0x7191c90> - AMBIGUOUS LAYOUT | | | | *<UILabel:0x7194080> - AMBIGUOUS LAYOUT | | | *<UIView:0x7191d70> - AMBIGUOUS LAYOUT | | | | *<UILabel:0x71948f0> - AMBIGUOUS LAYOUT | | | *<UIView:0x7191e50> - AMBIGUOUS LAYOUT | | | | *<UILabel:0x7194f90> - AMBIGUOUS LAYOUT | | | *<UIView:0x7191f30> - AMBIGUOUS LAYOUT | | | | *<UILabel:0x71955a0> - AMBIGUOUS LAYOUT
That’s a lot of ambiguity! As a matter of fact, by only pinning the tabs to the left edge, there is nothing giving width to any of the views. We can dig further into the problem of a specific view by calling constraintsAffectingLayoutForAxis on a view in the debugger.
(lldb) po [0x7191be0 constraintsAffectingLayoutForAxis:0] (id) $8 = 0x0719bdf0 <__NSArrayM 0x719bdf0>( <NSLayoutConstraint:0x7193ed0 H:|-(0)-[UIView:0x7191be0] (Names: '|':UIView:0x718ff70 )>, <NSLayoutConstraint:0x7195b00 UIView:0x7191f30.width == UIView:0x7191e50.width>, <NSLayoutConstraint:0x71953f0 UIView:0x7191e50.width == UIView:0x7191d70.width>, <NSLayoutConstraint:0x7194770 UIView:0x7191c90.width == UIView:0x7191be0.width>, <NSLayoutConstraint:0x7194e10 UIView:0x7191d70.width == UIView:0x7191c90.width> )
Looking at the constraints returned, you can see that one of the problem views only has a pin to the left edge and width equality with four other views. Nothing forces the view to have a non-zero width, and so it has collapsed. By re-adding the pin to the right edge, you get the nicely spaced layout that was intended.
Safari Books Online has the content you need
Below are some iOS books to help you develop apps for Apple’s popular platform, or you can check out all of the iOS books and training videos available from Safari Books Online. You can browse the content in preview mode or you can gain access to more information with a free trial or subscription to Safari Books Online.
Check out these iOS books available from Safari Books Online:
|The “Live Code,” app-driven approach used in this beautiful four-color book is simply the best way for working developers to master iOS programming. Using iOS 6 for Programmers, Second Edition, developers learn by creating 15 complete, fully tested iPhone/iPad/iPod Touch Apps, and in the process study 8,000+ lines of program code, including code that reveals the power of Apple’s newest iOS 6 SDK. In addition, this edition contains a detailed case study focusing on iOS SDK features exclusive to iPad/iPad 2.|
|iOS 5 Essentials will help you learn how to build simple, yet powerful iOS 5 applications incorporating iCloud Storage, Twitter, Core Image and Newsstand integration.|
|iOS 5 Programming Cookbook contains more than 100 new iOS 5 recipes covering iCloud, Automatic Reference Counting, storyboarding, graphics, animations, Grand Central Dispatch, threads, timers, audio and video and many other iOS 5 tools and techniques.|
|Assuming only a minimal working knowledge of Objective-C, and written in a friendly, easy-to-follow style, Beginning iOS 5 Development offers a complete soup-to-nuts course in iPhone, iPad, and iPod touch programming.|
About the Author
|Allen Pike is a co-founder of Steamclock Software, where he and his team build wonderful apps for iOS and the web. Besides building software, he designs, teaches, and writes.|