哪个布局约束优先于同等优先级?
Which layout constraint precedes with equal priority?
给定两个约束:
NSLayoutConstraint.activate([
aView.topAnchor.constraint(equalTo: cView.topAnchor) //#1
aView.topAnchor.constraint(greaterThanOrEqualTo: bView.bottomAnchor, constant: 10) //#2
])
让我们假设约束 #1 中的 cView.topAnchor
小于(即 "further up north")约束 #2 中的 bView.bottomAnchor
。
这不应该导致自动布局冲突吗,因为它不能满足两个约束,因为它们具有相同的优先级?
奇怪的是它没有 - 至少不在日志 window 中,也不在 Xcode 的调试视图层次结构中。
我的方法是将约束 #1 的优先级设置为 .defaultHigh
,以便自动布局可以打破约束而不会发生冲突。
难道还需要设置优先级吗,好像没什么冲突?
基于文档的解释
具有相同优先级的两个(或多个)约束不能同时满足总是会导致冲突。根据 documentation:
When the system detects a unsatisfiable layout at runtime, it performs the following steps:
Auto Layout identifies the set of conflicting constraints.
It breaks one of the conflicting constraints and checks the layout. The system continues to break constraints until it finds a valid layout.
Auto Layout logs information about the conflict and the broken constraints to the console.
文档没有指定打破了哪个约束 - 它是有意的,因此您不会依赖它,而是 明确决定应该通过降低优先级来打破哪个约束。
实证评估
您可以通过设置两个绝对冲突的约束来简单地测试行为:
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)>
奇怪的是,如果您指定两个冲突的约束,其中两个约束的优先级都低于要求的优先级 ('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
and 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`,没有理由让自动布局识别冲突。
另外,如果没有约束.required
,即使有也不会报冲突
给定两个约束:
NSLayoutConstraint.activate([
aView.topAnchor.constraint(equalTo: cView.topAnchor) //#1
aView.topAnchor.constraint(greaterThanOrEqualTo: bView.bottomAnchor, constant: 10) //#2
])
让我们假设约束 #1 中的 cView.topAnchor
小于(即 "further up north")约束 #2 中的 bView.bottomAnchor
。
这不应该导致自动布局冲突吗,因为它不能满足两个约束,因为它们具有相同的优先级?
奇怪的是它没有 - 至少不在日志 window 中,也不在 Xcode 的调试视图层次结构中。
我的方法是将约束 #1 的优先级设置为 .defaultHigh
,以便自动布局可以打破约束而不会发生冲突。
难道还需要设置优先级吗,好像没什么冲突?
基于文档的解释
具有相同优先级的两个(或多个)约束不能同时满足总是会导致冲突。根据 documentation:
When the system detects a unsatisfiable layout at runtime, it performs the following steps:
Auto Layout identifies the set of conflicting constraints.
It breaks one of the conflicting constraints and checks the layout. The system continues to break constraints until it finds a valid layout.
Auto Layout logs information about the conflict and the broken constraints to the console.
文档没有指定打破了哪个约束 - 它是有意的,因此您不会依赖它,而是 明确决定应该通过降低优先级来打破哪个约束。
实证评估
您可以通过设置两个绝对冲突的约束来简单地测试行为:
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)>
奇怪的是,如果您指定两个冲突的约束,其中两个约束的优先级都低于要求的优先级 ('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
and 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`,没有理由让自动布局识别冲突。
另外,如果没有约束.required
,即使有也不会报冲突