哪个布局约束优先级相同?

问题描述 投票:1回答:1

鉴于两个限制:

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,这样自动布局可以打破约束而不会发生冲突。

因此,甚至有必要设置优先级,因为似乎没有冲突?

ios autolayout nslayoutconstraint
1个回答
2
投票

基于文档的解释

具有相同优先级且无法同时满足的两个(或更多)约束总是会导致冲突。根据documentation

当系统在运行时检测到不可满足的布局时,它将执行以下步骤:

  1. 自动布局标识一组冲突的约束。
  2. 它打破了一个冲突的约束并检查布局。系统继续破坏约束,直到找到有效的布局。
  3. 自动布局将有关冲突和已损坏约束的信息记录到控制台。

文档没有指定哪个约束被破坏 - 它是有意的,因此您不会依赖它,而是通过降低其优先级来明确决定应该破坏哪个约束。


实证评估

您可以通过设置两个明确冲突的约束来简单地测试行为:

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.topa.top >= b.bottom', which can be satisfied ifc.top> = b.bottom. So unless there are other constraints with the same priority that conflict withc.top> = b.bottom`,autolayout没有理由识别冲突。

此外,如果约束不是.required,即使存在冲突,也不会报告冲突。

© www.soinside.com 2019 - 2024. All rights reserved.