无法以编程方式在swift中设置NSLayoutConstraint乘数..."无法分配此表达式的结果

Jak*_*eso 7 constraints ios autolayout nslayoutconstraint swift

我试图以编程方式设置swift中乘数的约束,当我设置值时,它只是给我错误,"不能分配给这个表达式的结果"......

我用一个IBOutlet声明了NSLayoutConstraint,然后设置乘数,就像我对另一个常量一样,这很好,但是这个不会接受它......

@IBOutlet weak var clockWidthConstraint: NSLayoutConstraint!

override func updateViewConstraints() {
    super.updateViewConstraints()

    confirmTopConstraint.constant = 40.0
    clockWidthConstraint.multiplier = 0.1  // Gives me the error!

    }
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Chr*_*ver 6

是的,这是只读的:

var multiplier: CGFloat { get } 
Run Code Online (Sandbox Code Playgroud)

您只能在创建时指定乘数.相反,您可以constant在运行时更改非常量属性:

var constant: CGFloat
Run Code Online (Sandbox Code Playgroud)

编辑:

它需要一点点努力,但是要更改不可变属性,您必须创建一个新约束并复制除要更改的属性之外的所有属性.我一直在玩这种不同的技术,但我目前正在探索这种形式:

let constraint = self.aspectRatioConstraint.with() {
    (inout c:NSLayoutConstraint.Model) in
    c.multiplier = self.aspectRatio }
Run Code Online (Sandbox Code Playgroud)

或在更现实的背景下使用:

var aspectRatio:CGFloat = 1.0 { didSet {

    // remove, update, and add constraint
    self.removeConstraint(self.aspectRatioConstraint)
    self.aspectRatioConstraint = self.aspectRatioConstraint.with() {
        (inout c:NSLayoutConstraint.Model) in
        c.multiplier = self.aspectRatio }
    self.addConstraint(self.aspectRatioConstraint)
    self.setNeedsLayout()
}}
Run Code Online (Sandbox Code Playgroud)

支持代码是:

extension NSLayoutConstraint {

    class Model {

        init(item view1: UIView, attribute attr1: NSLayoutAttribute,
            relatedBy relation: NSLayoutRelation,
            toItem view2: UIView?, attribute attr2: NSLayoutAttribute,
            multiplier: CGFloat, constant c: CGFloat,
            priority:UILayoutPriority = 1000) {
                self.firstItem = view1
                self.firstAttribute = attr1
                self.relation = relation
                self.secondItem = view2
                self.secondAttribute = attr2
                self.multiplier = multiplier
                self.constant = c
                self.priority = priority
        }

        var firstItem:UIView
        var firstAttribute:NSLayoutAttribute
        var relation:NSLayoutRelation
        var secondItem:UIView?
        var secondAttribute:NSLayoutAttribute
        var multiplier:CGFloat = 1.0
        var constant:CGFloat = 0
        var priority:UILayoutPriority = 1000
    }


    func priority(priority:UILayoutPriority) -> NSLayoutConstraint {
        self.priority = priority;
        return self
    }

    func with(configure:(inout Model)->()) -> NSLayoutConstraint {

        // build and configure model
        var m = Model(
            item: self.firstItem as! UIView, attribute: self.firstAttribute,
            relatedBy: self.relation,
            toItem: self.secondItem as? UIView, attribute: self.secondAttribute,
            multiplier: self.multiplier, constant: self.constant)
        configure(&m)

        // build and return contraint from model
        var constraint = NSLayoutConstraint(
            item: m.firstItem, attribute: m.firstAttribute,
            relatedBy: m.relation,
            toItem: m.secondItem, attribute: m.secondAttribute,
            multiplier: m.multiplier, constant: m.constant)
        return constraint
    }
}
Run Code Online (Sandbox Code Playgroud)