添加/删除约束时,自动布局有多宽容?

时间:2014-07-17 00:11:10

标签: ios autolayout

添加和删除约束时,自动布局系统有多宽松?它会导致崩溃,警告,或者在我错误地使用它时不会发生任何事情吗?

特别是,当我执行以下操作时会发生什么?

  1. 删除目标不拥有的约束?
  2. 添加目标已拥有的约束?
  3. 向最近共同祖先上方的视图添加约束?
  4. 向最近共同祖先下方的视图添加约束?
  5. 将视图已拥有的约束添加到新的(有效)视图?

1 个答案:

答案 0 :(得分:5)

想象一下,我们有以下UIView层次结构:

  • grandFather
    • father
      • target
        • son
          • grandson
    • uncle

我们定义了4个约束(grandFatherConstraintfatherConstrainttargetConstraintsonConstraint),这些约束只是将命名视图附加在其下方。约束的所有者是最近的共同祖先,恰好是约束名称中提到的祖先(例如grandFatherConstraintgrandFather拥有)。

例如,grandFatherConstraint引脚grandFatherfather,使grandFather成为此约束的最近共同祖先。同样,targetConstraint引脚targetsontarget是最近的共同祖先。

1。删除不属于目标的约束?

  • 由后代拥有? (例如[target removeConstraint:sonConstraint]
  • 祖先拥有? (例如[target removeConstraint:grandFatherConstraint]
  • 拥有不同的观点? (例如[target removeConstraint:uncleConstraint]
  • 什么都没有? (例如[target removeConstraint:nothingConstraint]
  • 查看哪些只是约束的一部分,但仍然不是所有者? (例如[target removeConstraint:fatherConstraint]

在所有这些情况下,没有任何反应。约束不会被删除。

这是根据removeConstraint:文档预期的行为:

  

删除视图未保留的约束无效。

2。添加目标已拥有的约束?

示例:[target addConstraint:targetConstraint]

没有任何反应,它不会再次添加约束。

3。向一个高于最近共同祖先的视图添加约束?

示例:[target addConstraint:newSonConstraint]

所有内容都会显示正确,但约束的所有者将不是最近的共同祖先,这可能(或可能不)是您想要的行为。换句话说,它会将约束附加到您指定的视图(target),而不是查找并将其附加到最近的共同祖先(son)。

这可能是可取的原因是因为约束的所有者在某些情况下是重要的。来自addConstraint:文档:

  

添加到视图的约束被认为是由该视图保存的。评估约束时使用的坐标系是保存约束的视图的坐标系。

4。向一个低于最近共同祖先的视图添加约束?

示例:[target addConstraint:newFatherConstraint]

这会导致崩溃。

安装约束后,将记录以下内容:

  

视图层次结构没有为约束准备:[...]
      添加到视图时,约束的项必须是该视图(或视图本身)的后代。如果在组装视图层次结构之前需要解析约束,则会崩溃。打破 - [UIView _viewHierarchyUnpreparedForConstraint:]进行调试。

将控制权释放到主运行循环后,您将收到以下消息的崩溃:

  

视图层次结构未准备好约束。
      约束:[...]
      容器层次结构:[...]
      在容器层次结构中找不到视图:[...]
      该视图的超级视图:[...]

这是根据addConstraint:文档预期的行为:

  

约束可能只引用视图本身或其子视图。

5。将视图已拥有的约束添加到新的(有效)视图中?

示例:[father addConstraint:targetConstraint]

这是一个有趣的场景,没有完整记录。运行上述代码时,它将首先从当前所有者(target)中删除约束,然后将其重新分配给您指定的新视图(father)。

因此,上述代码基本上变为:

[target removeConstraint:targetConstraint]
[father addConstraint:targetConstraint]