AutoLayout:UIView中的UIView帧不正确

时间:2015-02-19 08:38:06

标签: ios cocoa-touch uiview autolayout uistoryboard

我在Storyboard中使用AutoLayout,一切似乎都很顺利。但是,当我将一个UIView放入另一个UIView并将所有约束应用于容器及其子容器时,我注意到viewDidLayoutSubviews:中的框架不正确。考虑到我的约束,它不是我期望计算的框架,而是一些令人作呕的大框架(虽然在正确的原点)。例如,而不是 {{26,10},{444,10}} 的框架,我得到的内容类似于 {{0,0},{320,568}}

奇怪的是,当我将它放在另一个UIView中时,这个只发生只发生在子UI​​View上,这个UIView在它的superview(这是视图控制器的视图)方面有一些约束。由于我的印象是我可以根据方法viewDidLayoutSubviews:中的约束条件正确地构建我的观点,所以我很困惑为什么会发生这种情况。

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

注意:如果我在viewDidAppear:中执行与帧相关的正确设置,则此问题已完全解决,但这对我来说是一种不太令人满意的解决方法。

1 个答案:

答案 0 :(得分:19)

自动布局更改为边界不一定在-viewDidLayoutSubviews中完成。正如"Advance Auto Layout Toolbox"所述:

  

基于约束的布局是一个迭代过程。布局传递可以   根据以前的布局解决方案更改约束,   它再次触发更新另一个布局后的约束   通过。

-viewDidLayoutSubviews notes with emphasis in the original的文档:

  

但是,这个名为的方法不会表示视图子视图的各个布局已经过调整。

因此,子视图中基于布局和约束的迭代可以继续调整其帧,但是如果ViewController的视图边界没有改变,则不会调用其-viewWillLayoutSubviews

由于您说您的设置是“依赖于帧”,因此您有两个选项。

  1. -viewWillAppear中进行设置。优于-viewDidAppear,因为你真的需要在所有布局完成之后但在它出现在屏幕之前完成所有事情,这是该方法存在的合理原因。如果相关,您可以尝试拨打-isMovingToParentViewControllerDetermining Why A View's Appearance Changed中所述。
  2. 在您需要的视图上调用-layoutIfNeeded,以获得所需的正确值。因为这样做布局工作它很昂贵,并且如果在其自己的布局过程中触发,它可能导致重复工作或甚至无限循环。但如果需要将某些值与自动布局同步以便可以使用它们,那么它很有用。
  3. 如果这不起作用,请告诉我们,这可能与约束本身的性质或其他因素有关。自动布局迭代可能很难与之同步。祝好运。