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

时间:2018-03-02 15:58:56

标签: ios autolayout nslayoutconstraint

考虑到两个限制因素:

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

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

1 个答案:

答案 0 :(得分:2)

基于文档的说明

具有相同优先级且无法同时满足的两个(或更多)约束始终会导致冲突。根据{{​​3}}:

  

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

     
      
  1. 自动布局识别出一组冲突的约束。

  2.   
  3. 它打破了一个冲突的约束并检查布局。系统会继续破坏约束,直到找到有效的布局。

  4.   
  5. 自动布局将有关冲突和已损坏约束的信息记录到控制台。

  6.   

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

经验评估

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

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)>

奇怪的是,如果你指定两个冲突的约束,其中两个约束的优先级低于所需的优先级(&#39;优先级&lt; 1000&#39;),冲突将存在,模糊行为,但你不会得到警告在控制台中。小心一点。您可以使用以下方法对其进行测试:

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 if c.top&gt; = b.bottom . So unless there are other constraints with the same priority that conflict with c.top&gt; = b.bottom`,自动布局没有理由识别冲突

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