175

I created two views in one superview, and then added constraints between views:

_indicatorConstrainWidth = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view2 attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f];
[_indicatorConstrainWidth setPriority:UILayoutPriorityDefaultLow];
_indicatorConstrainHeight = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view2 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f];
[_indicatorConstrainHeight setPriority:UILayoutPriorityDefaultLow];
[self addConstraint:_indicatorConstrainWidth];
[self addConstraint:_indicatorConstrainHeight];

Now I want to change multiplier property with animation, but I can't figure out how to change the multipler property. (I found _coefficient in private property in header file NSLayoutConstraint.h, but it private.)

How do I change multipler property?

My workaround is to remove the old constraint and add the new one with a different value for multipler.

Cristik
  • 30,989
  • 25
  • 91
  • 127
Bimawa
  • 3,535
  • 2
  • 25
  • 45
  • 1
    Your current approach of removing old constraint and adding new one is the right choice. I understand that it doesn't feel "right", but it's the way you're supposed to do it. – Rob Oct 25 '13 at 15:39
  • 4
    I think multiplier should not be constant. It is a bad design. – Borzh Feb 09 '15 at 22:52
  • 1
    @Borzh why through multipliers i make adaptive constraints. For resizeble ios. – Bimawa Feb 10 '15 at 06:35
  • 2
    Yes, I also want to change multiplier so views can keep it's ratio to parent view (not both width/heigth but just width or height), but the strange thing that apple doesn't allow it. I mean it is Apple's bad design, not yours. – Borzh Feb 10 '15 at 17:34
  • This is a great talk and covers this and more https://www.youtube.com/watch?v=N5Ert6LTruY – DogCoffee Dec 16 '15 at 05:56
  • I just needed to resize views so i came here. It seems there is no easy way to do it. So i decided to change constant and well it worked. If you're here to resize your views just [constraint setConstant: (someFloat) ]. – EFE May 12 '16 at 08:51
  • @Bimawa: Mathematics is against you. Changing the multiplier means that all the layout constraints have to be solved completely again. Changing the constant is much much simpler mathematically. – gnasher729 Jan 21 '18 at 21:12
  • @gnasher729 yea as Flexbox much much simpler autolayouts ) – Bimawa Jan 21 '18 at 23:29

18 Answers18

202

Here is an NSLayoutConstraint extension in Swift that makes setting a new multiplier pretty easy:

In Swift 3.0+

import UIKit
extension NSLayoutConstraint {
    /**
     Change multiplier constraint

     - parameter multiplier: CGFloat
     - returns: NSLayoutConstraint
    */
    func setMultiplier(multiplier:CGFloat) -> NSLayoutConstraint {

        NSLayoutConstraint.deactivate([self])

        let newConstraint = NSLayoutConstraint(
            item: firstItem,
            attribute: firstAttribute,
            relatedBy: relation,
            toItem: secondItem,
            attribute: secondAttribute,
            multiplier: multiplier,
            constant: constant)

        newConstraint.priority = priority
        newConstraint.shouldBeArchived = self.shouldBeArchived
        newConstraint.identifier = self.identifier

        NSLayoutConstraint.activate([newConstraint])
        return newConstraint
    }
}

Demo usage:

@IBOutlet weak var myDemoConstraint:NSLayoutConstraint!

override func viewDidLoad() {
    let newMultiplier:CGFloat = 0.80
    myDemoConstraint = myDemoConstraint.setMultiplier(newMultiplier)

    //If later in view lifecycle, you may need to call view.layoutIfNeeded() 
}
Andrew Schreiber
  • 14,344
  • 6
  • 46
  • 53
  • 13
    `NSLayoutConstraint.deactivateConstraints([self])` should be done before creating `newConstraint`, otherwise it may result in warning: _Unable to simultaneously satisfy constraints_. Also `newConstraint.active = true` is unnecessary since `NSLayoutConstraint.activateConstraints([newConstraint])` does exactly same thing. – zalogatomek Jul 05 '16 at 15:41
  • Hi @andrewSchreiber. Awesome. Why the "weak" in particular man, is there a reason? thx. – Fattie Jul 14 '16 at 19:16
  • 1
    activate and deactivate does not work before ios8 , is there any alternative for that ?? – narahari_arjun Nov 17 '16 at 07:06
  • @narahari_arjun http://stackoverflow.com/questions/31167248/deactive-nslayoutconstraint-ios7 – Cœur Jan 01 '17 at 19:23
  • This is brilliant! I took the liberty of changing the example multiplier value in the final example of "50" (!) to something realistic. :) awesome post! – Fattie Jan 24 '17 at 20:26
  • 2
    This does not work when changing the multiplier again, it gets a nil value – J. Doe Jul 17 '17 at 19:58
  • 4
    Thanks for saving us time! I would rename the function to something like `cloneWithMultiplier` to make it more explicit that it doesn't just apply side effects but rather returns an new constraint – Alexandre G Aug 01 '17 at 01:21
  • Just a note on swift three you would be writing `setMultipler(multipler: 80)` so I just removed multiplier from the function name to match the Swift 3 naming style – Jesse Onolemen Aug 18 '17 at 16:40
  • @tzaloga awesome! you helped me clear tons of constraint warnings in my project. thank you a lot! – Joey Nov 22 '17 at 01:54
  • 1
    Heads up. `item: firstItem,` gives a warning - "Expression implicitly coerced from AnyObject? to Any" – Jonny Jan 26 '18 at 05:11
  • 1
    This is great and (as far as I can see) should always work. But *sometimes* the old constraint remains active, and of course conflicts with the new constraint. Even when I deactivate the old one *again* at the call site, just to be anal. Why would a deactivated constraint reactivate? There are of course other approaches like changing priorities or marking Uninstalled and installing at runtime... – Andrew Duncan Feb 13 '18 at 20:26
  • Why return it?? – mskw Jul 12 '18 at 21:22
  • 6
    Note that if you set the multiplier to `0.0` you will not be able to update it again. – Daniel Storm Jan 02 '19 at 16:38
  • @DanielStorm what's the reason which isn't working with `0.0` and is there any solution in that case? – rener172846 Oct 16 '19 at 19:27
  • @rener172846 no idea why this happens. Set the multiplier to something minute, like `0.001`. – Daniel Storm Oct 16 '19 at 20:15
  • @DanielStorm instead 0.001 make firstItem.isHidden true/false – john07 Dec 30 '19 at 06:10
  • this causes layout constraint conflicts unless you uninstall the constraint in interface builder. How to do this without having to uninstall the constraint from interface builder? – Joseph Astrahan Jan 15 '20 at 00:35
  • okay I found solution to fix the conflict! (https://stackoverflow.com/questions/27494542/when-can-i-activate-deactivate-layout-constraints), according to this, in interface builder adjust the priority to be 'low' on your constraint in question. Then on this function change the priority line to this (newConstraint.priority = UILayoutPriority.defaultHigh). Everything will work since the high priority will overide the old installed but interface builder won't have the warnings anymore! – Joseph Astrahan Jan 15 '20 at 01:21
  • You should also check if it was active originally before re-activating. Also this will fail if NSLayoutConstraint gets new properties. This is only a patch unfortunately. – ScottyBlades May 28 '21 at 17:43
131

If you have only have two sets of multipliers that need to be applied, from iOS8 onwards you can add both sets of constraints and decide which should be active at any time:

NSLayoutConstraint *standardConstraint, *zoomedConstraint;

// ...
// switch between constraints
standardConstraint.active = NO; // this line should always be the first line. because you have to deactivate one before activating the other one. or they will conflict.
zoomedConstraint.active = YES;
[self.view layoutIfNeeded]; // or using [UIView animate ...]

Swift 5.0 version

var standardConstraint: NSLayoutConstraint!
var zoomedConstraint: NSLayoutConstraint!

// ...

// switch between constraints
standardConstraint.isActive = false // this line should always be the first line. because you have to deactivate one before activating the other one. or they will conflict.
zoomedConstraint.isActive = true
self.view.layoutIfNeeded() // or using UIView.animate
Nikita
  • 460
  • 5
  • 11
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Can you animate this change in constraints? ie: animate turning off multiplier constraint 0.75 and turning on multiplier constraint 0.3 and have it animate fluidly like constraint animations already do? – micnguyen Jun 13 '15 at 06:54
  • 2
    @micnguyen Yes, you can :) – Ja͢ck Jun 13 '15 at 06:55
  • 11
    If you need more than 2 sets of constraints, you can add as many as you want and change their priority properties. This way, for 2 constraints you don't have to set one to active and the other one as inactive, you just set the priority higher or lower. On above example, set standardConstraint priority to, let's say 997, and when you want it to be active just set zoomedConstraint's priority to 995, otherwise set it to 999. Also make sure the XIB doesn't have the priorities set to 1000, otherwise you won't be able to change them and you'll get an awesome crash. – Dog Jul 06 '15 at 12:02
  • 1
    @WonderDog does that have any particular advantage, though? the idiom of enabling and disabling seems to me easier to digest than having to work out relative priorities. – Ja͢ck Jul 06 '15 at 12:04
  • @Jack well, you write less code and for n constraints you don't have to set n-1 constraints as inactive every time. – Dog Jul 06 '15 at 12:14
  • @WonderDog Seems like the wrong tool for the job to be honest, but I like the alternative angle :) – Ja͢ck Jul 06 '15 at 13:34
  • 3
    @WonderDog / Jack I wound up combining your approaches because my constraint was defined in the storyboard. And if I created two contraints, both with the same priority but different multipliers, they conflicted and gave me lots of red. And from what I can tell you can't set one as inactive via IB. So I created my main constraint with priority 1000 and my secondary constraint that I want to animate to with priority 999 (plays nice in IB). Then inside an animation block, I set the primary one's active property to false and it animated nicely to the secondary one. Thanks both for the help! – Clay Garrett Oct 28 '15 at 12:44
  • how to add "inactive" constraint from story board ? – Mihir Mehta Dec 18 '15 at 10:31
  • not work for me. The view disappear at runtime after add 2 constraints of it. – oOEric Feb 10 '16 at 16:20
  • 3
    Keep in mind that you probably want strong references to your constraints if activating & deactivating them, since "Activating or deactivating the constraint calls `addConstraint(_:)` and `removeConstraint(_:)` on the view that is the closest common ancestor of the items managed by this constraint". – qix Jan 04 '17 at 05:26
60

The multiplier property is read only. You have to remove the old NSLayoutConstraint and replace it with a new one to modify it.

However, since you know you want to change the multiplier, you can just change the constant by multiplying it yourself when changes are needed which is often less code.

Fruity Geek
  • 7,351
  • 1
  • 32
  • 41
  • 70
    Does seem odd that multiplier is read only. I wasn't expecting that! – jowie Jul 08 '14 at 15:53
  • 156
    @jowie it's ironic that the "constant" value can be changed while the multiplier cannot. – Tomas Andrle Feb 19 '15 at 08:56
  • 7
    This is wrong. An NSLayoutConstraint specifies an affine (in)equality constraint. For example: "View1.bottomY = A * View2.bottomY + B" 'A' is the multiplier, 'B' is the constant. No matter how you tune B, it won't produce the same equation as changing A's value. – Tamás Zahola Apr 21 '15 at 13:45
  • @TamásZahola That's exactly the point of the solution. You can't change the `multiplier`. So instead, you specify the `multiplier` as 1.0. The formula for calculating the constraint's `constant` would be: `(realMultiplier - 1.0) * View2.bottomY + realConstant` – Fruity Geek Apr 21 '15 at 20:51
  • 9
    @FruityGeek okay, so you're using `View2.bottomY`'s _current_ value to calculate the constraint's _new_ constant. That's flawed, since `View2.bottomY`'s old value will be baked in the constant, so you have to give up the declarative style and manually update the constraint anytime `View2.bottomY` changes. In this case you might aswell do manual layout. – Tamás Zahola Apr 22 '15 at 13:49
  • 2
    This will not work in case, when I want NSLayoutConstraint to respond for bounds change or device rotation without extra code. – zalogatomek Jul 05 '16 at 14:40
  • 1
    Yeah, as Tomas said is funny you can change the constant but not the multiplier. Seems very confusing to me and I believe it would be much better if I can change the multiplier in order to change the constant. – Sebastian Paduano Oct 26 '18 at 08:19
53

A helper function I use to change multiplier of an existing layout constraint. It creates and activates a new constraint and deactivates the old one.

struct MyConstraint {
  static func changeMultiplier(_ constraint: NSLayoutConstraint, multiplier: CGFloat) -> NSLayoutConstraint {
    let newConstraint = NSLayoutConstraint(
      item: constraint.firstItem,
      attribute: constraint.firstAttribute,
      relatedBy: constraint.relation,
      toItem: constraint.secondItem,
      attribute: constraint.secondAttribute,
      multiplier: multiplier,
      constant: constraint.constant)

    newConstraint.priority = constraint.priority

    NSLayoutConstraint.deactivate([constraint])
    NSLayoutConstraint.activate([newConstraint])

    return newConstraint
  }
}

Usage, changing multiplier to 1.2:

constraint = MyConstraint.changeMultiplier(constraint, multiplier: 1.2)
Evgenii
  • 36,389
  • 27
  • 134
  • 170
45

Objective-C Version for Andrew Schreiber answer

Create the category for NSLayoutConstraint Class and add the method in .h file like this

    #import <UIKit/UIKit.h>

@interface NSLayoutConstraint (Multiplier)
-(instancetype)updateMultiplier:(CGFloat)multiplier;
@end

In the .m file

#import "NSLayoutConstraint+Multiplier.h"

@implementation NSLayoutConstraint (Multiplier)
-(instancetype)updateMultiplier:(CGFloat)multiplier {

    [NSLayoutConstraint deactivateConstraints:[NSArray arrayWithObjects:self, nil]];

   NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:self.firstItem attribute:self.firstAttribute relatedBy:self.relation toItem:self.secondItem attribute:self.secondAttribute multiplier:multiplier constant:self.constant];
    [newConstraint setPriority:self.priority];
    newConstraint.shouldBeArchived = self.shouldBeArchived;
    newConstraint.identifier = self.identifier;
    newConstraint.active = true;

    [NSLayoutConstraint activateConstraints:[NSArray arrayWithObjects:newConstraint, nil]];
    //NSLayoutConstraint.activateConstraints([newConstraint])
    return newConstraint;
}
@end

Later in the ViewController create the outlet for the constraint you want to update.

@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;

and update the multiplier where ever you want like below..

self.topConstraint = [self.topConstraint updateMultiplier:0.9099];
Jules
  • 7,568
  • 14
  • 102
  • 186
Koti Tummala
  • 746
  • 6
  • 8
  • I’ve moved deactivate in this sample code as `active = true` is the same as activate and therefore causes a duplicate constraint to be added before deactivate is called, this causes a constraints error in some scenarios. – Jules Dec 28 '17 at 08:12
15

You can change the "constant" property instead to achieve the same goal with a little math. Assume your default multiplier on the constraint is 1.0f. This is Xamarin C# code which can be easily translated to objective-c

private void SetMultiplier(nfloat multiplier)
{
    FirstItemWidthConstraint.Constant = -secondItem.Frame.Width * (1.0f - multiplier);
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Tianfu Dai
  • 159
  • 1
  • 5
  • this is a nice solution – J. Doe Jul 17 '17 at 20:10
  • 3
    This will break if secondItem's frame changes width after the above code is executed. It's ok if secondItem will never change size, but if secondItem does change size then the constraint will no longer calculate the correct value for the layout. – John Stephen Aug 23 '18 at 21:24
  • As pointed out by John Stephen, this will not work for dynamic views, devices: it doesn't automatically update along with layout. – Womble Jul 08 '19 at 04:18
  • 2
    Great solution for my case, in which the second item's width is actually [UIScreen mainScreen].bounds.size.width (that never changes) – Arik Segal Jan 02 '20 at 08:44
13

As is in other answers explained: You need to remove constraint and create new one.


You can avoid returning new constraint by creating static method for NSLayoutConstraint with inout parameter, which allows you to reassign passed constraint

import UIKit

extension NSLayoutConstraint {

    static func setMultiplier(_ multiplier: CGFloat, of constraint: inout NSLayoutConstraint) {
        NSLayoutConstraint.deactivate([constraint])

        let newConstraint = NSLayoutConstraint(item: constraint.firstItem, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: constraint.secondItem, attribute: constraint.secondAttribute, multiplier: multiplier, constant: constraint.constant)

        newConstraint.priority = constraint.priority
        newConstraint.shouldBeArchived = constraint.shouldBeArchived
        newConstraint.identifier = constraint.identifier

        NSLayoutConstraint.activate([newConstraint])
        constraint = newConstraint
    }

}

Example usage:

@IBOutlet weak var constraint: NSLayoutConstraint!

override func viewDidLoad() {
    NSLayoutConstraint.setMultiplier(0.8, of: &constraint)
    // view.layoutIfNeeded() 
}
Robert Dresler
  • 10,580
  • 2
  • 22
  • 40
8

in Swift 5.x you can use:

extension NSLayoutConstraint {
    func setMultiplier(multiplier: CGFloat) -> NSLayoutConstraint {
        guard let firstItem = firstItem else {
            return self
        }
        NSLayoutConstraint.deactivate([self])
        let newConstraint = NSLayoutConstraint(item: firstItem, attribute: firstAttribute, relatedBy: relation, toItem: secondItem, attribute: secondAttribute, multiplier: multiplier, constant: constant)
        newConstraint.priority = priority
        newConstraint.shouldBeArchived = self.shouldBeArchived
        newConstraint.identifier = self.identifier
        NSLayoutConstraint.activate([newConstraint])
        return newConstraint
    }
}
Radu Ursache
  • 1,230
  • 1
  • 22
  • 35
8

Swift 5+

Based on Evgenii's answer, here is an elegant way to change the multiplier through extension.

extension NSLayoutConstraint {
    func change(multiplier: CGFloat) {
        let newConstraint = NSLayoutConstraint(item: firstItem,
                                               attribute: firstAttribute,
                                               relatedBy: relation,
                                               toItem: secondItem,
                                               attribute: secondAttribute,
                                               multiplier: multiplier,
                                               constant: constant)

        newConstraint.priority = self.priority

        NSLayoutConstraint.deactivate([self])
        NSLayoutConstraint.activate([newConstraint])
    }
}

And the usage:

myConstraint.change(multiplier: 0.6)
Đorđe Nilović
  • 3,600
  • 1
  • 25
  • 20
6

NONE OF THE ABOVE CODE WORKED FOR ME SO AFTER TRYING TO MODIFY MY OWN CODE THIS CODE This code is working in Xcode 10 and swift 4.2

import UIKit
extension NSLayoutConstraint {
/**
 Change multiplier constraint

 - parameter multiplier: CGFloat
 - returns: NSLayoutConstraintfor 
*/i
func setMultiplier(multiplier:CGFloat) -> NSLayoutConstraint {

    NSLayoutConstraint.deactivate([self])

    let newConstraint = NSLayoutConstraint(
        item: firstItem,
        attribute: firstAttribute,
        relatedBy: relation,
        toItem: secondItem,
        attribute: secondAttribute,
        multiplier: multiplier,
        constant: constant)

    newConstraint.priority = priority
    newConstraint.shouldBeArchived = self.shouldBeArchived
    newConstraint.identifier = self.identifier

    NSLayoutConstraint.activate([newConstraint])
    return newConstraint
}
}



 @IBOutlet weak var myDemoConstraint:NSLayoutConstraint!

override func viewDidLoad() {
let newMultiplier:CGFloat = 0.80
myDemoConstraint = myDemoConstraint.setMultiplier(newMultiplier)

//If later in view lifecycle, you may need to call view.layoutIfNeeded() 
 }
Ullas Pujary
  • 349
  • 4
  • 14
3

Simple answer, no extensions required. I tried for my case, worked fine for me.

So as multiplier is a get only property, we can simply set multiplier in the following way :

yourConstraintOutlet.setValue(yourDesiredMultiplierValue, forKey: "multiplier")

yourConstraintOutlet.setValue(0.75, forKey: "multiplier")
Ashish Bahl
  • 1,482
  • 1
  • 18
  • 27
2

Yes w can change multiplier values just make an extension of NSLayoutConstraint and use it like ->

   func setMultiplier(_ multiplier:CGFloat) -> NSLayoutConstraint {

        NSLayoutConstraint.deactivate([self])

        let newConstraint = NSLayoutConstraint(
            item: firstItem!,
            attribute: firstAttribute,
            relatedBy: relation,
            toItem: secondItem,
            attribute: secondAttribute,
            multiplier: multiplier,
            constant: constant)

        newConstraint.priority = priority
        newConstraint.shouldBeArchived = shouldBeArchived
        newConstraint.identifier = identifier

        NSLayoutConstraint.activate([newConstraint])
        return newConstraint
    }

            self.mainImageViewHeightMultiplier = self.mainImageViewHeightMultiplier.setMultiplier(375.0/812.0)
Rajan Singh
  • 202
  • 2
  • 7
1

Switch by changing the active constraint in code as suggested by many other answers did not work for me. So i created 2 constrains, one installed and the other not, bind both to the code, and then switch by removing one and adding the other.

For the sake of completeness, to bind the constrain drag the constrain to the code using mouse right button, just like any other graphic element:

enter image description here

I named one proportionIPad and the other proportionIPhone.

Then, add the following code, at viewDidLoad

override open func viewDidLoad() {
   super.viewDidLoad()
   if ... {

       view.removeConstraint(proportionIphone)
       view.addConstraint(proportionIpad) 
   }     
}

I am using xCode 10 and swift 5.0

MiguelSlv
  • 14,067
  • 15
  • 102
  • 169
  • I did something similar, but actually you only need to have 1 constraint linked. The second one may be added with a lower priority, then removing constraint 1 will activate constraint 2 automatically. – Michael Pirotte Jul 08 '21 at 13:34
0

Here is an answer based on @Tianfu's answer in C#. Other answers that require activation and deactivation of constraints did not work for me.

    var isMapZoomed = false
@IBAction func didTapMapZoom(_ sender: UIButton) {
    let offset = -1.0*graphHeightConstraint.secondItem!.frame.height*(1.0 - graphHeightConstraint.multiplier)
    graphHeightConstraint.constant = (isMapZoomed) ? offset : 0.0

    isMapZoomed = !isMapZoomed
    self.view.layoutIfNeeded()
}
RawMean
  • 8,374
  • 6
  • 55
  • 82
0

@IBOutlet weak var viewHeightConstraint: NSLayoutConstraint!

let heightOfSuperview = self.view.bounds.height

viewHeightConstraint.constant = heightOfSuperview * 0.5

// this has the same effect as multiplier

-1

I have a way. No need to re-create a constraint.

Assuming you have an imageView which you want to constraint its aspect ratio to match the image aspect ratio.

  1. Create an aspect ratio constraint for the imageView and set multiplier to 1 and constant to 0.
  2. Create an outlet for the aspect ratio constraint.
  3. Change the constraint constant value at runtime, according the the image you load:
let multiplier = image.size.width / image.size.height
let (w, h) = (imageView.bounds.width, imageView.bounds.height)
let expectedW = h * multiplier
let diff = expectedW - h
imageViewAspectConstraint.constant = image.size.width >= image.size.height ? diff : -diff  // multiplier is read-only, but constant is RW
Papillon
  • 317
  • 2
  • 10
-1

note that you can simply yourConstraint.setValue(0.75, forKey: "multiplier")

or

Xcode 13.3.1, Swift 5.6 (swiftlang-5.6.0.323.62 clang-1316.0.20.8)

This is based on @Ullas Pujary's answer and I make it a little swifter and remove the warnings on firstItemandsecondItem`

extension NSLayoutConstraint {
    public static func setMultiplier(_ newMultiplier: CGFloat, of constraint: inout NSLayoutConstraint) {
        constraint.isActive = false
        
        guard
            let firstItem = constraint.firstItem,
            let secondItem = constraint.secondItem
        else {
            return
        }
        
        
        let newConstraint = NSLayoutConstraint(item: firstItem,
                                               attribute: constraint.firstAttribute,
                                               relatedBy: constraint.relation,
                                               toItem: secondItem,
                                               attribute: constraint.secondAttribute,
                                               multiplier: newMultiplier,
                                               constant: constraint.constant)
        
        newConstraint.priority = constraint.priority
        newConstraint.shouldBeArchived = constraint.shouldBeArchived
        newConstraint.identifier = constraint.identifier
        
        newConstraint.isActive = true
        constraint = newConstraint
    }
}
Fattie
  • 27,874
  • 70
  • 431
  • 719
infinity_coding7
  • 434
  • 5
  • 16
-2

One can read:

var multiplier: CGFloat
The multiplier applied to the second attribute participating in the constraint.

on this documentation page. Doesn't that mean that one should be able to modify multiplier (since it is a var)?

Michel
  • 10,303
  • 17
  • 82
  • 179
  • `var multiplier: CGFloat { get }` is the definition which means it does only have a getter. – Jonny May 09 '18 at 10:42