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

AutoLayout: UIView within UIView has incorrect frame

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

奇怪的是,当我将它放在另一个 UIView 中时,这个 发生在子 UIView 中,该 UIView 对其应用了一些与其父视图相关的约束(这是视图控制器的看法)。因为我的印象是我可以根据我在方法 viewDidLayoutSubviews: 中的限制来正确地布置我的观点,所以我很困惑为什么会这样。

我是否做出了错误的假设?如果有人可以帮助我指出正确的方向,我将不胜感激。谢谢!

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

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

Constraint-based layout is an iterative process. The layout pass can make changes to the constraints based on the previous layout solution, which again triggers updating the constraints following another layout pass.

-viewDidLayoutSubviewsnotes with emphasis in the original的文档:

However, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted.

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

既然你说你的设置是“依赖于帧的”,你有几个选择。

1.在 -viewWillAppear 中进行设置。比 -viewDidAppear 更好,并且由于您确实需要在完成所有布局之后完成所有工作 但在它出现在屏幕上之前,这是该方法存在的合理原因。如果相关,您可以尝试致电 -isMovingToParentViewControllerDetermining Why A View's Appearance Changed.

中所述

编辑:-viewWillAppear 在视图添加到视图层次结构之前被调用,因此布局 可能不会 完成。对不起大家,谢天谢地 Swift UI 我们正在从过程式布局转向声明式布局,这就是原因。


  1. 在您需要的视图上调用 -layoutIfNeeded,以便在需要的地方具有正确的值。因为这会进行布局工作,所以它很昂贵,并且如果在其自己的布局过程中触发,可能会导致重复性工作甚至无限循环。但如果需要将某些值与自动布局同步以便使用它们,它会很有用。

如果这不起作用,请告诉我们,这可能与约束本身的性质或其他原因有关。自动布局迭代可能很难同步。祝你好运。