iOS 8顶级布局指导自动布局问题

时间:2014-09-21 21:31:43

标签: ios iphone autolayout ios8

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

这就是iOS 7上的视图:

iOS 7 Screen

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

iOS 7 Screen

如您所见,视图显示在导航栏上方。 顶部布局指南有两个约束,一个用于上部图像视图,另一个用于下面的白色视图。 底部布局指南没有约束,只有视图的高度限制。

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

iOS 8中的哪些内容可能会破坏布局?

[编辑] 以下是视图约束的完整列表:

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

5 个答案:

答案 0 :(得分:43)

默认情况下,在“属性”检查器的“扩展边缘”部分中选中

Extend Edges > Under Top Bars

尝试取消选中Under Top Bars

当我出现这种奇怪的行为时,这对我有很多帮助。

请注意它是一个UIViewController属性,因此如果您愿意,可以在代码中设置它。

Under Top Bars option in Interface Builder

答案 1 :(得分:5)

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

解决此问题的最佳和最简单的方法是将视图控制器嵌入到导航控制器中,就是这样。您可以通过选择视图控制器并转到编辑器&gt;来完成。嵌入&gt;导航控制器。(如果旧导航栏上有任何内容,您可以先将其拖放,将视图控制器嵌入导航控制器,然后移动新导航栏上的栏按钮,然后删除旧导航巴)

将导航栏的translucent属性设置为NO

self.navigationController.navigationBar.translucent = NO;

这将修复视图在导航栏和状态栏下面的框架。

如果您必须显示和隐藏导航栏,请使用

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

viewDidLoad方法中。

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

答案 2 :(得分:5)

我正在使用Xcode 6.3.1,似乎该版本中的错误(据说它已在5.1中修复)。我无法在SO上找到解决办法,所以我不得不谷歌更多,这里是:

而不是在IB中执行常规的Ctrl +拖动,只需选择要执行此操作的视图,然后转到编辑器 - &gt; Pin - &gt; Superview的顶级空间。

以下是来源:LINK 它对我的情况有帮助。

答案 3 :(得分:2)

也有这样的问题。如果仅在iOS8上运行,则可以更改&#34; topLayoutGuide.bottom-myView.top&#34;中的约束。 to&#34; topLayoutGuide.top-myView.top&#34;。但这将打破iOS7的UI。可以在代码中编写类似的解决方法以支持这两个版本,但是在故事板中创建UI时,没有机会使两个版本的UI运行良好。

答案 4 :(得分:-4)

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

如果你的视图控制器在storyboard中的大小是600x600,那么在viewDidLoad中,它将获得视图控制器视图的那个框架并相应地布局子视图。

希望这会有所帮助..