利用约束优先级解决AutoLayout冲突

最近使用AutoLayout遇到了个问题。具体的来说,有个使用Xib创建的TableViewCell,其中用AutoLayout布局的。布局如下

Cell手稿
由于业务需要,有时候需要动态加载Cell,考虑一些方案后采取把Cell高度设置为0.01的方法。但这样会导致一堆错误信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2015-12-30 19:29:16.526 autolayout[28645:2090707] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x7a6667a0 V:[UIView:0x7a666580]-(10)-| (Names: '|':UITableViewCellContentView:0x7a666480 )>",
"<NSLayoutConstraint:0x7a666800 V:|-(10)-[UIView:0x7a666580] (Names: '|':UITableViewCellContentView:0x7a666480 )>",
"<NSLayoutConstraint:0x7a65fff0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7a666480(0.49)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7a6667a0 V:[UIView:0x7a666580]-(10)-| (Names: '|':UITableViewCellContentView:0x7a666480 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

这个错误在iOS7上可能引起崩溃。仔细查看Log主要是是因为把内部View上下设置为相对于Cell相差10。但是如果Cell高度为0.01,则因为View高度不能为负的,所以会不能安全满足约束条件。

这种情况下,可以通过修改约束的优先级(Priority)来解决问题。默认情况下约束优先级为1000。此时我们修改底部约束优先级为900即可解决问题。
修改约束优先级
当出现约束冲突时,主动放弃低优先级的约束。

使用Snapkit等AutoLayout扩展时也能相应的修改约束优先级来解决问题,如

1
2
3
4
box.snp_makeConstraints { (make) -> Void in
make.height.equalTo(50).priority(900) //方便动态修改高度,避免冲突
make.center.equalTo(self.view)
}