3

How can I modify the multiplier of a constraint programmatically? I have set the following:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0]];

and I need to modify it to this:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
Imanou Petit
  • 84,140
  • 26
  • 249
  • 211
Jason Bestor
  • 99
  • 1
  • 2
  • 10

5 Answers5

5

You won't be able to change the multiplier because it is readonly. You would have to store a reference to the constraint. Then when you want to change the multiplier you would remove the constraint and add a new one.

You could include a method like this in your view controllers implementation:

- (void)changeMultiplier:(NSLayoutConstraint **)constraint to:(CGFloat)newMultiplier{
    NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:(*constraint).firstItem attribute:(*constraint).firstAttribute relatedBy:(*constraint).relation toItem:(*constraint).secondItem attribute:(*constraint).secondAttribute multiplier:newMultiplier constant:(*constraint).constant];
    [self.view removeConstraint:(*constraint)];
    [self.view addConstraint:newConstraint];
    *constraint = newConstraint;
}

Related Questions:

Can i change multiplier property for NSLayoutConstraint?

Community
  • 1
  • 1
keji
  • 5,777
  • 3
  • 29
  • 47
4

For modifying multiplier I use switching between constraints method.
You must Create constraints with different priorities else it will break the layout.

Objective C

NSLayoutConstraint *constraint1, *constraint2;

// switch between constraints

constraint1.active = NO; 
constraint2.active = YES;
[self.view layoutIfNeeded];

Swift 2.0

self.constraint1.active = true
self.constraint2.active = false
self.view.layoutIfNeeded()
Abhishek Bedi
  • 4,677
  • 1
  • 33
  • 59
Faris Muhammed
  • 762
  • 11
  • 16
3

As others said, you have to delete the old one and add a new one. If you do not want to store it as a property, just set identifier and search to get it later

-(NSLayoutConstraint *)constraintWithIndientifer:(NSString *)identifer InView:(UIView *)view{
    NSLayoutConstraint * constraintToFind = nil;
    for (NSLayoutConstraint * constraint in view.constraints ) {
        if([constraint.identifier isEqualToString:identifer]){
            constraintToFind = constraint;
            break;
        }
    }
    return constraintToFind;
}

Then

NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:self.yellowView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
constraint.identifier = @"1234";
[self.view addConstraint:constraint];

Then you can get this

NSLayoutConstraint * constraint = [self constraintWithIndientifer:@"1234" InView:self.view];
pkamb
  • 30,595
  • 22
  • 143
  • 179
Leo
  • 24,180
  • 10
  • 68
  • 91
  • 1
    Thanks for the suggestions. I ended up using the constant instead. to keep it simple... `self.constraint = [NSLayoutConstraint constraintWithItem:_button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:(self.view.frame.size.width / 2)]; [self.view addConstraint:_newsWidthConstraint];` and then later I edited it to make it full width... `self.constraint.constant = self.view.frame.size.width;` – Jason Bestor Jun 10 '15 at 01:01
2

There's an easier way to modify the multiplier of a constraint programmatically using Layout Anchors:

imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 1.0/2.0).isActive = true

Here's how it works:

Result view

Eugene Brusov
  • 15,771
  • 6
  • 50
  • 68
0

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")

No extensions required and no need to multiply by superview height/width.

Ashish Bahl
  • 1,436
  • 1
  • 14
  • 26