自动布局:updateConstraints 不会在方向更改时得到调用
Posted
技术标签:
【中文标题】自动布局:updateConstraints 不会在方向更改时得到调用【英文标题】:Autolayout: updateConstraints doesn't get call on orientation change 【发布时间】:2015-07-14 07:25:48 【问题描述】:我正在学习自动布局在 ios 中的工作原理。为此,我创建了一个示例单视图应用程序,它具有一个视图控制器(它是初始视图控制器)和一个自定义视图(我们称之为示例视图)。我在 Main.storyboard 的视图控制器中添加了示例视图,并带有自动布局约束。我在带有自动布局约束的示例视图中添加了一个按钮和一个标签。我覆盖了 SampleView.m 中的 layoutSubviews 和 updateConstraints 方法。这些被覆盖的方法除了调用它们的超级实现之外什么都不做。我为这两种方法添加了一个断点并开始调试应用程序。以下是我的观察
我发现在 SampleView 的 layoutSubviews 方法之前调用了 updateConstraints。但是,我阅读了一些帖子/答案,其中提到 layoutSubviews 在 updateConstraints 之前被调用。现在我很困惑什么是正确的机制?在 layoutSubviews 之前调用 updateConstraint,反之亦然。自动布局系统如何工作?
当我将设备从纵向旋转到横向或从横向旋转到纵向时,我发现 SampleView 的 updateConstraints 方法不会自动调用(但是 layoutSubviews 方法会自动调用),而我阅读了一些帖子/答案这表示在轮换时,updateConstraints 方法会自动调用。我再次困惑哪一个是真的?
如果 updateConstrains 方法没有在方向改变时自动调用,那么当方向改变时,我们如何在视图层次结构中的所有视图上调用 updateConstraint 方法?会在父视图上调用 setNeedsUpdateConstraint 吗,会在该视图的所有子视图上调用 updateConstraint 吗?
【问题讨论】:
【参考方案1】:布局过程一般是这样的:
第一步:更新约束,自下而上进行。通过调用 [view setNeedsUpdateConstraints] 触发,覆盖自定义视图的 [view updateConstraints]。这一步解决了约束。
第二步:布局,自上而下。通过调用 [view setNeedsLayout]、[view layoutIfNeeded] 触发,覆盖自定义视图的 [view layoutSubviews]。当 layoutSubviews 被调用时,我们有框架。
第三步:显示,发生自上而下。通过调用[view setNeedsDisplay]触发,覆盖自定义视图的[view drawRect:]。
所以,
updateConstraints 发生在 layoutSubviews 之前。约束基本上是添加到视图的父视图中的对象,描述了如何布局父视图的子视图。所以您确实需要在布局发生之前更新约束。
在方向改变时,约束没有改变,因此我认为不会调用 updateConstraints。
当方向改变时,我们如何在视图层次结构中的所有视图上调用 updateConstraint 方法?约束不需要更新,因为它们是视图应该如何相互关联的方式。相反,当方向改变时,最顶层视图 (UIWindow) 的框架将被更新,因此它的所有子视图都需要更新它们的框架以符合您之前设置的约束。 p>
如果我错了,请纠正我:)
【讨论】:
@Mousam 关于您在这里的较早问题,我添加了一些想法 - 希望对您有所帮助!【参考方案2】:这很混乱。
看待它的一种方式是:对于不同的方向,您可能会有不同的约束。
这适用于 iOS 中的整个特征系统。 (你必须 1000% 熟悉,才能处理这个问题!:O)
考虑一个令人难以置信的自定义视图...
(注意 - 几乎可以肯定,这意味着视图会随着大小的变化而连续动画,这通常是这种视图的全部观点。)
在令人难以置信的自定义视图中,您将不断地“修改约束”....
但这意味着您将修改......“一个方向的约束”(即使这些,碰巧,目前没有被使用)......并且......你将修改“另一个方向的约束”(即使 那些,碰巧,目前没有被使用)。
您使用 updateConstraints() 来修改“所有”约束(在大多数情况下,基于动画/更改视图大小连续进行) - 这意味着 all所有特征变化的约束,所有时间 - !
这是看待问题的一种重要方式!
【讨论】:
以上是关于自动布局:updateConstraints 不会在方向更改时得到调用的主要内容,如果未能解决你的问题,请参考以下文章