iOS 8 顶部布局指南自动布局问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25964076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:40:46  来源:igfitidea点击:

iOS 8 top layout guide auto layout problems

iosiphoneautolayoutios8

提问by David Ganster

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.

更新到 iOS 8 SDK 时,我的应用程序中的一个屏幕完全坏了。问题似乎是顶部布局指南向上移动而不是作为其余视图的“锚点”。

This is what the view looked like on iOS 7:

这是视图在 iOS 7 上的样子:

iOS 7 Screen

iOS 7 屏幕

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

这是它在 iOS 8 中的样子(从 Xcode 6 View Hierarchy 调试器捕获):

iOS 7 Screen

iOS 7 屏幕

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.

出于某种原因,iOS 8 决定将顶部布局指南推送到第一次调用{0 -255; 0 0}之后[self.view layoutIfNeeded]。此外,视图的边界有时对于设备来说显得太大(即与统一故事板(600x600)完全相同,而不是 320x480/320x568。

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

iOS 8 中哪些更改可能会破坏布局?

[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]>
)

回答by Blacky

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

Extend Edges > Under Top Bars默认情况下,在 Attribute Inspector 的 Extend Edges 部分中选中。

Try unchecking Under Top Bars.

尝试取消选中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.

请注意它是一个 UIViewController 属性,因此您可以根据需要在代码中设置它。

Under Top Bars option in Interface Builder

在界面生成器中的顶部栏选项下

回答by Mrunal

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

您可以使用UIBarPositionTopAttached或您可以使用视图边界和框架,我也可以建议您并将您链接到Apple 的文档,这需要您花一些时间来解决问题。

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)

解决这个问题的最好和最简单的方法是将你的视图控制器嵌入到导航控制器中,就是这样。您只需选择视图控制器并转到 Editor > Embed In > Navigation Controller 即可完成此操作。(如果旧导航栏有内容,可以先往下拉,将视图控制器嵌入到导航控制器中,然后移动新导航栏上的栏按钮,然后删除旧导航栏)

OR

或者

Set the navigation bar's translucentproperty to NO:

将导航栏的translucent属性设置为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 viewDidLoadmethod.

在你的viewDidLoad方法中。

Hope either of these will solve your issue.

希望其中任何一个都能解决您的问题。

回答by JakeP

I'm using Xcode 6.3.1 and it seems the bug is back in that version (supposedly it was fixed in 5.1). I wasn't able to find a work-around on SO so I had to google some more and here it is:

我正在使用 Xcode 6.3.1 并且该错误似乎又回到了该版本(据说它已在 5.1 中修复)。我无法在 SO 上找到解决方法,所以我不得不在谷歌上搜索更多,它是:

instead of doing the usual Ctrl+drag in IB, just select the View you want to do this for and go to Editor -> Pin -> Top Space to Superview.

而不是在 IB 中执行通常的 Ctrl+drag,只需选择您想要执行此操作的视图,然后转到 Editor -> Pin -> Top Space to Superview。

Here's the source: LINKIt helped in my case.

这是来源:LINK它对我的情况有所帮助。

回答by Nikita Ivaniushchenko

Also have a problem like that. If running on iOS8 only, you can change constraints from "topLayoutGuide.bottom-myView.top" to "topLayoutGuide.top-myView.top". But that will break UI for iOS7. It's possible to write workaround like that in code to support both versions, but there is no chance to make UI working well for both versions when creating UI in storyboards.

也有这样的问题。如果仅在 iOS8 上运行,您可以将约束从“topLayoutGuide.bottom-myView.top”更改为“topLayoutGuide.top-myView.top”。但这会破坏 iOS7 的 UI。可以在代码中编写类似的解决方法来支持两个版本,但是在故事板中创建 UI 时,没有机会使 UI 对两个版本都能很好地工作。

回答by Henit Nathwani

Instead of using the unified storyboard (600x600), you should keep one of the device resolutions for your interface builder and then layout your screen in IB.

不要使用统一的故事板 (600x600),您应该为您的界面构建器保留一种设备分辨率,然后在 IB 中布局您的屏幕。

If your view controller's size is 600x600 in storyboard, then in viewDidLoad, it will get that frame for your view controller's view and layout the subviews accordingly.

如果您的视图控制器在故事板中的大小为 600x600,那么在 viewDidLoad 中,它将为您的视图控制器的视图获取该框架并相应地布局子视图。

Hope this helps..

希望这可以帮助..