iosiphoneobjective-cnslayoutconstraint

Can I change multiplier property for NSLayoutConstraint?


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.


Solution

  • 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