如何设置 Swift 中约束的优先级?

How can I set priority on constraints in Swift?

我一直在努力在 Swift 中以编程方式优先处理约束工作。

我的目标是 meetingFormView 宽度不超过 300。使用 IB,我会给宽度约束一个较低的优先级,并给“lessThanOrEqualToConstant”一个较高的优先级。但是我无法让它工作。

我试过这个:

meetingFormView.translatesAutoresizingMaskIntoConstraints = false

let constraintWidth = NSLayoutConstraint(
        item: meetingFormView,
        attribute: NSLayoutAttribute.width,
        relatedBy: NSLayoutRelation.equal,
        toItem: startView,
        attribute: NSLayoutAttribute.width,
        multiplier: 1,
        constant: 0)
constraintWidth.priority = .defaultHigh

NSLayoutConstraint.activate([
    meetingFormView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
    meetingFormView.heightAnchor.constraint(equalToConstant: 170),
    meetingFormView.widthAnchor.constraint(lessThanOrEqualToConstant: 300),
    meetingFormView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    constraintWidth
])

实际上似乎需要 行代码才能在代码中设置优先 "anchor-based" 约束:

let widthConstraint = meetingFormView.widthAnchor.constraint(equalToConstant: 170)
widthConstraint.priority = UILayoutPriority(rawValue: 500)
widthConstraint.isActive = true

似乎如果我尝试使用 let 设置 isActive 声明 Xcode(也许 Swift?)无法识别类型是 NSLayoutConstraint。使用 UILayoutPriority(rawValue:) 似乎是设置优先级的最佳(唯一?)方法。

虽然这个答案不完全符合您正在做的事情,但我相信它适用于 IB。只需将 let 替换为创建 IBOutlet 即可,不需要 isActive 行。

显然,要在后面的代码中更改优先级,您只需要:

widthConstraint.priority = UILayoutPriority(rawValue: 750)

你可以这样写一个小扩展:

extension NSLayoutConstraint
{
    func withPriority(_ priority: Float) -> NSLayoutConstraint
    {
        self.priority = UILayoutPriority(priority)
        return self
    }
}

然后像这样使用它:

NSLayoutConstraint.activate([
    ...
    meetingFormView.widthAnchor.constraint(lessThanOrEqualToConstant: 300).withPriority(500),
    ...
])