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

Sen*_*ful 3 ios autolayout

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

特别是,当我做以下事情时会发生什么?

  1. 删除不属于目标的约束?
  2. 添加目标已拥有的约束?
  3. 向一个高于最近共同祖先的视图添加约束?
  4. 向一个低于最近共同祖先的视图添加约束?
  5. 将视图已拥有的约束添加到新(有效)视图?

Sen*_*ful 5

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

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

我们已经定义4个约束(grandFatherConstraint,fatherConstraint,targetConstraint,和sonConstraint),其简单地固定与所述一个右下方的命名视图.约束的所有者是最近的共同祖先,恰好是约束名称中提到的祖先(例如grandFatherConstraint,由其拥有grandFather).

例如,grandFatherConstraintgrandFatherfather,使得grandFather该约束的最近的共同祖先.同样,targetConstraint引脚targetson,并且target是最近的共同祖先.

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

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

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

根据removeConstraint: document:这是预期的行为:

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

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

例: [target addConstraint:targetConstraint]

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

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

例: [target addConstraint:newSonConstraint]

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

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

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

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

例: [target addConstraint:newFatherConstraint]

这会导致崩溃.

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

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

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

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

根据addConstraint: document:这是预期的行为:

约束可能仅引用视图本身或其子视图.

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

例: [father addConstraint:targetConstraint]

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

因此,上面的代码基本上变成:

[target removeConstraint:targetConstraint]
[father addConstraint:targetConstraint]
Run Code Online (Sandbox Code Playgroud)