鉴于两个限制:
NSLayoutConstraint.activate([
aView.topAnchor.constraint(equalTo: cView.topAnchor) //#1
aView.topAnchor.constraint(greaterThanOrEqualTo: bView.bottomAnchor, constant: 10) //#2
])
让我们假设约束#1中的cView.topAnchor
比约束#2中的bView.bottomAnchor
更小(即“更向上”)。
这不应该导致自动布局的冲突,因为它不能满足这两个约束因为它们具有相同的优先级吗?
奇怪的是它没有 - 至少不在日志窗口中,也不在Xcode的调试视图层次结构中。
我的方法是将约束#1的优先级设置为.defaultHigh
,这样自动布局可以打破约束而不会发生冲突。
因此,甚至有必要设置优先级,因为似乎没有冲突?
基于文档的解释
具有相同优先级且无法同时满足的两个(或更多)约束总是会导致冲突。根据documentation:
当系统在运行时检测到不可满足的布局时,它将执行以下步骤:
- 自动布局标识一组冲突的约束。
- 它打破了一个冲突的约束并检查布局。系统继续破坏约束,直到找到有效的布局。
- 自动布局将有关冲突和已损坏约束的信息记录到控制台。
文档没有指定哪个约束被破坏 - 它是有意的,因此您不会依赖它,而是通过降低其优先级来明确决定应该破坏哪个约束。
实证评估
您可以通过设置两个明确冲突的约束来简单地测试行为:
NSLayoutConstraint.activate([
view.heightAnchor.constraint(equalToConstant: 81),
view.heightAnchor.constraint(equalToConstant: 60),
])
这将导致冲突并将在控制台中报告:
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:0x1c0099550 molly.QuestionInboxLinkPreView:0x10791dd40.height == 81 (active)>",
"<NSLayoutConstraint:0x1c008c300 molly.QuestionInboxLinkPreView:0x10791dd40.height == 60 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1c0099550 molly.QuestionInboxLinkPreView:0x10791dd40.height == 81 (active)>
奇怪的是,如果你指定两个冲突的约束,其中两个约束的优先级低于required('priority <1000'),那么冲突将存在,模糊的行为,但你不会在控制台中收到警告。小心一点。你可以用以下方法测试它:
let constraint1 = view.heightAnchor.constraint(equalToConstant: 81)
constraint1.priority = UILayoutPriority(rawValue: 999)
let constraint2 = view.heightAnchor.constraint(equalToConstant: 60)
constraint2.priority = UILayoutPriority(rawValue: 999)
NSLayoutConstraint.activate([constraint1, constraint2])
我想原因是,由于破坏的约束不是required
,系统不足以报告它。但它可能会导致一些丑陋的情况 - 注意它并小心它。
你的例子
现在考虑你的例子:
NSLayoutConstraint.activate([
aView.topAnchor.constraint(equalTo: cView.topAnchor) //#1
aView.topAnchor.constraint(greaterThanOrEqualTo: bView.bottomAnchor, constant: 10) //#2
])
只是这两个约束不一定是冲突的。你说的是a.top = c.top
和a.top >= b.bottom', which can be satisfied if
c.top> = b.bottom. So unless there are other constraints with the same priority that conflict with
c.top> = b.bottom`,autolayout没有理由识别冲突。
此外,如果约束不是.required
,即使存在冲突,也不会报告冲突。