添加和删除约束时,自动布局系统有多宽松?它会导致崩溃,警告,或者在我错误地使用它时不会发生任何事情吗?
特别是,当我执行以下操作时会发生什么?
答案 0 :(得分:5)
想象一下,我们有以下UIView
层次结构:
grandFather
father
target
son
grandson
uncle
我们定义了4个约束(grandFatherConstraint
,fatherConstraint
,targetConstraint
和sonConstraint
),这些约束只是将命名视图附加在其下方。约束的所有者是最近的共同祖先,恰好是约束名称中提到的祖先(例如grandFatherConstraint
由grandFather
拥有)。
例如,grandFatherConstraint
引脚grandFather
到father
,使grandFather
成为此约束的最近共同祖先。同样,targetConstraint
引脚target
至son
和target
是最近的共同祖先。
[target removeConstraint:sonConstraint]
)[target removeConstraint:grandFatherConstraint]
)[target removeConstraint:uncleConstraint]
)[target removeConstraint:nothingConstraint]
)[target removeConstraint:fatherConstraint]
)在所有这些情况下,没有任何反应。约束不会被删除。
这是根据removeConstraint:文档预期的行为:
删除视图未保留的约束无效。
示例:[target addConstraint:targetConstraint]
没有任何反应,它不会再次添加约束。
示例:[target addConstraint:newSonConstraint]
所有内容都会显示正确,但约束的所有者将不是最近的共同祖先,这可能(或可能不)是您想要的行为。换句话说,它会将约束附加到您指定的视图(target
),而不是查找并将其附加到最近的共同祖先(son
)。
这可能是可取的原因是因为约束的所有者在某些情况下是重要的。来自addConstraint:文档:
添加到视图的约束被认为是由该视图保存的。评估约束时使用的坐标系是保存约束的视图的坐标系。
示例:[target addConstraint:newFatherConstraint]
这会导致崩溃。
安装约束后,将记录以下内容:
视图层次结构没有为约束准备:[...]
添加到视图时,约束的项必须是该视图(或视图本身)的后代。如果在组装视图层次结构之前需要解析约束,则会崩溃。打破 - [UIView _viewHierarchyUnpreparedForConstraint:]进行调试。
将控制权释放到主运行循环后,您将收到以下消息的崩溃:
视图层次结构未准备好约束。
约束:[...]
容器层次结构:[...]
在容器层次结构中找不到视图:[...]
该视图的超级视图:[...]
这是根据addConstraint:文档预期的行为:
约束可能只引用视图本身或其子视图。
示例:[father addConstraint:targetConstraint]
这是一个有趣的场景,没有完整记录。运行上述代码时,它将首先从当前所有者(target
)中删除约束,然后将其重新分配给您指定的新视图(father
)。
因此,上述代码基本上变为:
[target removeConstraint:targetConstraint]
[father addConstraint:targetConstraint]