AutoLayout:UIView中的UIView有不正确的框架

我正在使用故事板中的AutoLayout,并且一切似乎都很顺利。 但是,当我把一个UIView放在另一个里面,并且把所有的约束都应用到容器和它的子viewDidLayoutSubviews: ,我注意到这个框架在viewDidLayoutSubviews:是不正确的。 我不希望根据我的限制来计算这个框架,而是一些令人厌恶的大框架(尽pipe是在正确的起源)。 例如,而不是{{26,10},{444,10}}的框架,我得到了{{0,0},{320,568}}

奇怪的是, 这只发生在孩子UIView,当我把它放在另一个UIView,有一些约束适用于它的超视图(这是视图控制器的视图)。 由于我的印象是,根据我在viewDidLayoutSubviews:方法中的约束,我可以期待我的观点得到适当的布置viewDidLayoutSubviews:我很困惑,为什么会发生这种情况。

我做了什么不正确的假设? 如果有人能帮助我指出正确的方向,我将不胜感激。 谢谢!

注意:如果我在viewDidAppear:执行了正确的依赖于框架的设置,这个问题就完全解决了,但是这对我来说是一个不太令人满意的解决方法。

自动布局更改界限不一定在-viewDidLayoutSubviews完成。 正如“Advance Auto Layout Toolbox”中所提到的 :

基于约束的布局是一个迭代过程。 布局过程可以根据先前的布局解决scheme对约束进行更改,这会再次触发在另一个布局过程之后更新约束。

-viewDidLayoutSubviews的文档在原文中强调 :

但是,调用此方法并不表示视图子视图的各个布局已被调整。

因此,子视图中的布局和基于约束的迭代可以继续调整其框架,但是如果ViewController的视图边界不会改变,那么它的-viewWillLayoutSubviews将不会被调用。

既然你说你的设置是“框架依赖”,你有几个选项。

  1. 做你的设置在-viewWillAppear 。 比-viewDidAppear更好,因为在所有的布局完成之后,在屏幕出现之前,你确实需要完成所有工作,这就是为什么这个方法在那里的正当理由。 如果相关,您可以尝试调用-isMovingToParentViewController ,如确定为什么视图的外观已更改中所述 。
  2. 在视图上调用-layoutIfNeeded需要在需要的时候拥有正确的值。 因为这样做的布局工作是昂贵的,它可能导致重复性的工作,甚至在自己的布局过程中触发无限循环。 但是,如果需要使用自动布局同步某些值,以便可以使用它,则会很有用。

如果这不起作用,让我们知道,这可能与约束本身的性质或别的什么有关。 自动布局迭代可能很难同步。 祝你好运。