翻译@Auto Layout Guide(自动布局指南)
Debugging Auto Layout(Debug自动布局)
Unsatisfiable Layouts(布局无法满足)
如果当前约束无解,则系统认为布局无法满足。这是由于两个或以上约束互相冲突,无满被同时满足。
Identifying Unsatisfiable Constraints(定位错误)
IB能够在设计阶段发现约束冲突,以多种方式提醒开发者:
- 在画布上以红色表示冲突约束;
- 冲突约束以警告的形式显示在问题导航面板中;
场景对象列表(scene’s document outline)右上角出现红色箭头;

点击箭头,展开布局问题列表。
IB会为这些问题推荐解决方案。更多信息,详见自动布局帮助中解决控制器,窗口以及根视图布局问题的相关内容。
注意
尽管IB提供的即时反馈能极大减少出错的几率,但其无法涵盖所有布局错误。
举例来说,IB基于当前画布尺寸侦测错误。但某些冲突只有在画布尺寸(亦或是内容视图尺寸)大于或小于特定临界点时才会出现,IB对此无能为力。
同时,仅仅修复IB指出的错误是不够的。还需要在不同屏幕尺寸,方向,语言,动态字体环境下反复调试,让错误在运行时暴露出来。
App运行期间,如果系统发现布局无法满足,会执行以下操作:
- 定位冲突约束;
- 打破此约束,检测布局,重复这一动作,直至得到合法布局;
- 向控制台输出相关信息(冲突情况和被打破的约束的信息)。
这种妥协机制在尽最大努力挽救布局的同时, 保证app正常运行。然而,我们无法决定打破哪条约束,也无法控制这样做的后果。
有时,打破约束不会对布局效果产生影响;但有时,其会导致整套布局错位,缺失,甚至直接从屏幕上失踪。
布局效果不受影响时,错误信息很容易被人忽略——毕竟一切看起来都还OK。然而,视图结构的任何改变,甚至iOS SDK的变化,都可能导致系统打破其他约束,改变最终布局效果。
必须修复全部已知冲突。为了不遗漏,可以使用UIViewAlertForUnsatisfiableConstraints设置断点,捕捉约束冲突。
Preventing Unsatisfiable Constraints(预防错误)
这类问题相对来说较容易修复。因为系统会做出提示,推荐解决方案。
如前所述,问题通常难定位,易解决。解决的方式不外乎移除冲突约束,调整优先级。
但是,需要注意若干典型错误:
代码创建视图,布局无法满足。
视图属性translatesAutoresizingMaskIntoConstraints默认为
YES。IB创建视图时,此属性自动置为NO。代码创建视图时,需要手动修改。可用空间过小,布局无法满足。
通常开发者会对视图所在空间大小提前有所了解。然而,国际化和动态字体可能导致视图体积大于预期。情况越复杂,布局越容易发生冲突。
对此,可以采取妥协策略:如果某些条件无法达成,则有组织,有预期的主动放弃某些约束。
推荐的做法是将必要约束转化为高优先级约束。一旦冲突,这些约束会被打破。
举例来说,我们将约束优先级设置为
999。大多数情况下,其等同于必要约束;然而,一旦发生冲突,其会被打破,保护其他约束。与之类似,视图应该保持固有尺寸时,要避免将其外扩和内缩优先级设置为”必要”(1000),默认值已经是理想的妥协策略。或大或小,对布局没有实质影响。
的确,有些视图总是应该以固有尺寸视人;即便如此,相较于冲突,还不如容忍若干偏差。
