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:
This is what it looks like in iOS 8 (captured from the Xcode 6 View Hierarchy debugger):
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]> )
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With