Autolayout:updateConstraints没有调整方向更改

时间:2015-07-14 07:25:49

标签: ios objective-c iphone autolayout ios-autolayout

我正在学习自动布局如何在iOS中运行。为此我创建了一个示例单视图应用程序,它有一个视图控制器(初始视图控制器)和一个自定义视图(我们称之为示例视图)。我使用自动布局约束将示例视图添加到Main.storyboard中的视图控制器。我在Sample View中添加了一个按钮和一个标签,并带有自动布局约束。我重写了SampleView.m中的layoutSubviews和updateConstraints方法。这些被覆盖的方法只会调用它们的超级实现。我为这两种方法添加了一个断点并开始调试应用程序。以下是我的观察

  1. 我发现在SampleView中的layoutSubviews方法之前调用了updateConstraints。但是我读了几篇帖子/答案,其中提到在updateConstraints之前调用layoutSubviews。现在我很困惑什么是正确的机制? updateConstraint在layoutSubviews之前调用,反之亦然。自动布局系统如何工作?

  2. 当我将设备从纵向旋转到横向或从横向旋转到纵向时,我发现SampleView的updateConstraints方法没有自动调用(但是layoutSubviews方法会自动调用),而我读了几篇帖子/答案这表示在轮换时,updateConstraints方法会自动调用。我再次混淆哪一个是真的?

  3. 如果updateConstrains方法在方向更改时没有自动调用,那么当方向更改时,如何在视图层次结构中的所有视图上调用updateConstraint方法?将在父视图上调用setNeedsUpdateConstraint,是否会对该视图的所有子视图调用updateConstraint?

2 个答案:

答案 0 :(得分:7)

布局流程通常如下所示:

第一步:更新约束,自下而上发生。通过调用[view setNeedsUpdateConstraints]触发,覆盖自定义视图的[view updateConstraints]。此步骤解决了约束。

第二步:布局,自上而下发生。通过调用[view setNeedsLayout],[view layoutIfNeeded]触发,覆盖自定义视图的[view layoutSubviews]。当调用layoutSubviews时,我们有框架。

第三步:显示,自上而下发生。通过调用[view setNeedsDisplay]触发,覆盖[view drawRect:]以获取自定义视图。

所以,

  1. updateConstraints在layoutSubviews之前发生。约束基本上是添加到视图的父视图中的对象,描述了如何布局父视图的子视图。因此,确实需要在布局发生之前更新约束

  2. 关于方向更改,约束没有改变,因此我认为不会调用updateConstraints。

  3. 当方向发生变化时,如何在视图层次结构中的所有视图上调用updateConstraint方法?约束不需要更新,因为它们是关于视图应如何相互关联的方式。相反,当方向更改时,最顶层视图(UIWindow)框架将更新,因此其所有子视图都需要更新其框架,以便符合您之前设置的约束起来。

  4. 如果我错了,请纠正我:)

答案 1 :(得分:1)

这非常令人困惑。

一种看待它的方法是:对于不同的方向,您可能会有 不同的约束条件

这可与iOS中的整个traits系统一起使用。 (哪怕您必须对此有1000%的熟悉,才可以解决这个问题!:O)

考虑一个令人难以置信的自定义视图...

(请注意-几乎可以肯定,这意味着随着大小的变化,该视图会连续进行动画处理,这通常是该视图的全部要点。)

在难以置信的自定义视图中,您将连续地“修改约束” ....

但这意味着您将要修改...“某一方向的约束”(即使目前没有使用这些约束),并且...您将在修改“另一个方向的约束”(即使那些暂时没有被使用)。

您可以使用updateConstraints()来从“所有”约束条件中修改地狱(在大多数情况下,根据动画/更改视图的大小连续地修改)-这意味着所有 所有性状变异的约束,所有的时间-!

这是解决问题的一种重要方法!