如何设置 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),
...
])
我一直在努力在 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),
...
])