Cannot programmatically set the NSLayoutConstraint factor to swift ... "Cannot assign the result of this expression

I am trying to programmatically set a limit on a multiplier in swift, and when I set the value, it just gives me an error: "Unable to assign the result of this expression" ...

I declared NSLayoutConstraint with IBOutlet and then set a multiplier, like me, with a constant for another that works fine, but this one won't accept it ...

@IBOutlet weak var clockWidthConstraint: NSLayoutConstraint! override func updateViewConstraints() { super.updateViewConstraints() confirmTopConstraint.constant = 40.0 clockWidthConstraint.multiplier = 0.1 // Gives me the error! } 

Any ideas?

+6
source share
1 answer

Yes, this is read only:

 var multiplier: CGFloat { get } 

You can specify a multiplier only at creation time. Alternatively, you can change the variable property of constant at runtime:

 var constant: CGFloat 

Edit:

It takes a little effort, but to change immutable properties you need to create a new constraint and copy everything except the property you want to change. I continue to play with different tricks for this, but am currently studying this form:

 let constraint = self.aspectRatioConstraint.with() { (inout c:NSLayoutConstraint.Model) in c.multiplier = self.aspectRatio } 

or used in a more realistic context:

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

If the support code is:

 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 } } 
+5
source

Source: https://habr.com/ru/post/980787/


All Articles