Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 top layout guide auto layout problems

Tags:

One of the screens in my app completely broke when updating to the iOS 8 SDK. The problem seems to be that the top layout guide shifts up instead of being an 'anchor' for the rest of the views.

This is what the view looked like on iOS 7:

iOS 7 Screen

This is what it looks like in iOS 8 (captured from the Xcode 6 View Hierarchy debugger):

iOS 7 Screen

As you can see, the view appears way above the navigation bar. There are two constraints on the top layout guide, one for the upper image view, and one for the white view below it. There are no constraints on the bottom layout guide, only height constraints on the views.

For some reason, iOS 8 decides to push the top layout guide to {0 -255; 0 0} after [self.view layoutIfNeeded] is called for the first time. Also, the view's bounds sometimes appear too large for the device (i.e. showing up exactly as in the unified storyboard (600x600), instead of 320x480/320x568.

What has changed in iOS 8 that might screw up the layout?

[EDIT] Here is a complete list of the constraints on the view:

(lldb) po self.view.constraints <__NSArrayM 0x786ac520>(     <NSLayoutConstraint:0x7c377bd0 V:[_UILayoutGuide:0x7c372f60]-(0)-[UIView:0x7c373120]>,     <NSLayoutConstraint:0x7c377c00 UIView:0x7c373120.width == UIView:0x7c3730b0.width>,     <NSLayoutConstraint:0x7c377c30 UIView:0x7c3730b0.centerX == UIView:0x7c373120.centerX>,     <NSLayoutConstraint:0x7c377c60 H:|-(0)-[UIView:0x7c3716f0]   (Names: '|':UIView:0x7c3730b0 )>,     <NSLayoutConstraint:0x7c377c90 UIView:0x7c3716f0.width == UIView:0x7c3730b0.width>,     <NSLayoutConstraint:0x7c372f30 V:[_UILayoutGuide:0x7c372f60]-(129)-[UIView:0x7c3716f0]> ) 
like image 365
David Ganster Avatar asked Sep 21 '14 21:09

David Ganster


People also ask

What is iOS auto layout?

Auto Layout is the preferred technology to define layouts for user interfaces on iOS and macOS. Its goal: To make it easy for you to create user interfaces that adapt automatically to different screen sizes and orientations.

What is auto layout?

Auto layout is a property you can add to frames and components. It lets you create designs that grow to fill or shrink to fit, and reflow as their contents change. This is great when you need to add new layers, accommodate longer text strings, or maintain alignment as your designs evolve.

What are two properties that auto layout constraints control on a Uiview?

Auto Layout defines margins for each view. These margins describe the preferred spacing between the edge of the view and its subviews. You can access the view's margins using either the layoutMargins or layoutMarginsGuide property.


2 Answers

Extend Edges > Under Top Bars is checked by default in the Extend Edges section of the Attribute Inspector.

Try unchecking Under Top Bars.

This has helped me many times when I got strange behaviour like this.

Please note it's a UIViewController property, so you can set it in code if you'd like.

Under Top Bars option in Interface Builder

like image 172
Blacky Avatar answered Sep 22 '22 14:09

Blacky


You can either use UIBarPositionTopAttached or you can use view bounds and frames, i can also suggest and link you to Apple's documentation that would take some time for you to solve the issue.

The best and the most easiest way to solve this issue is to just embed your view controller inside a navigation controller and thats it. You can do it by just selecting the view controller and going to Editor > Embed In > Navigation Controller. (If there is any content on your old navigation bar, you can first drag it down, embed the view controller in navigation controller and then move the bar buttons on the new navigation bar and then delete the old navigation bar)

OR

Set the navigation bar's translucent property to NO:

self.navigationController.navigationBar.translucent = NO; 

This will fix the view from being framed underneath the navigation bar and status bar.

If you have to show and hide the navigation bar, then use

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])     self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific 

in your viewDidLoad method.

Hope either of these will solve your issue.

like image 26
Mrunal Avatar answered Sep 20 '22 14:09

Mrunal