翻译@Auto Layout Guide(自动布局指南)
Debugging Auto Layout(Debug自动布局)
Ambiguous Layouts(布局歧义)
构成布局的全体约束,产生两个及以上合法结构时,系统认为布局歧义。主要原因有两个:
当前约束不足以明确视图位置和尺寸。
找到歧义视图,补全约束,问题解决;
优先级相同的可选约束互相冲突,系统不知道该打破哪条约束。
通过区分优先级,明确应被打破的约束。(较低的被打破)
Detecting Ambiguous Layouts(定位错误)
同布局无法满足一样,IB也能发现布局歧义,并推荐解决方案;类似的,通过问题导航面板,场景对象列表(scene’s document outline),以及画布上的红色线条提醒开发者。更多信息,详见章节Identifying Unsatisfiable Constraints(识别无法满足的约束)。
同理,IB无法涵盖所有布局错误,有些问题只能在运行时暴露出来。
App运行时,如果发生歧义,系统会随机选择一个布局,很可能与预期不符。并且没有警告信息,无法通过断点捕捉。
因此,歧义相对来说更难定位。经常会发现,虽然结果与预期不符,但依然无法确定其到底是有歧义还是布局本身逻辑有问题。
幸运的是,我们可以利用一些Debug方法(仅供Debug使用)。在可以访问视图结构的地方打断点,通过控制台调用以下方法:
hasAmbiguousLayout,适用于iOS和OS X。针对错位视图调用,返回YES,代表frame有歧义。
exerciseAmbiguityInLayout,适用于iOS和OS X。针对布局中任意视图调用,系统会在推荐的解决方案之间切换。
- constraintsAffectingLayoutForAxis:,适用于iOS。针对视图调用,返回其当前方向上相关约束。
- constraintsAffectingLayoutForOrientation:,适用于OS X。针对视图调用,返回其当前方向上相关约束。
_autolayoutTrace
,iOS私有方法。针对视图调用,返回其所在视图结构的诊断信息。其中,歧义视图和属性translatesAutoresizingMaskIntoConstraints为YES的视图被标记。
调用时,必须使用Objective-C语法。例如,断点时,在控制台输入call [self.myView exerciseAmbiguityInLayout]
,表示调用myView
的视图方法exerciseAmbiguityInLayout
。类似的,在控制台输入po [self.myView autolayoutTrace]
,会输出包含myView
的视图结构的诊断信息。
注意
使用上述Debug方法之前,修复IB发现的所有问题。IB会尝试修复错误,这意味着它会自动补全约束,消除歧义。
结果就是
hasAmbiguousLayout
返回NO
;exerciseAmbiguityInLayout
没有任何效果;constraintsAffectingLayoutForAxis:
返回的约束与预期不符。