How to Change Multiplier Property For Nslayoutconstraint

Can I change multiplier property for NSLayoutConstraint?

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

iOS - Change the multiplier of constraint by Swift

Since multiplier is a read-only property and you can't change it, you need to replace the constraint with its modified clone.

You can use an extension to do it, like this:

Swift 4/5:

extension NSLayoutConstraint {
func constraintWithMultiplier(_ multiplier: CGFloat) -> NSLayoutConstraint {
return NSLayoutConstraint(item: self.firstItem!, attribute: self.firstAttribute, relatedBy: self.relation, toItem: self.secondItem, attribute: self.secondAttribute, multiplier: multiplier, constant: self.constant)
}
}

Usage:

let newConstraint = constraintToChange.constraintWithMultiplier(0.75)
view.removeConstraint(constraintToChange)
view.addConstraint(newConstraint)
view.layoutIfNeeded()
constraintToChange = newConstraint

Programmatically Change multiplier of Alignment Constraint of Center X / Y

So for Y, if you set the top of the image equal with a constant of 0 to the top of the superView. then enter this code:

@IBOutlet weak var topc: NSLayoutConstraint!


let heightOfSuperview = self.view.bounds.height
topc.constant = heightOfSuperview * 0.90 // this has the same effect as multiplier

This is equivalent of Center.y multiplier = 0.9:1

auto layout modify multiplier of constraint programmatically

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];

Need to change multiplier of NSLayoutConstraint according to device orientation: where to do it?

you can catch the orientation changes by overriding the method willTransitionToTraitCollection:withTransitionCoordinator: in view controller, and then can update the constraints accordingly. And yes as you have mentioned if you need to change multiplier then you will first have to remove the constraint and then apply it again. If you know at compile time what multiplier you would be using in both orientations then i would suggest to use interface builder to create separate constraints with different multipliers for distinct size classes.

Useful Material

Adaptive and Size Changes Reference

How can I change the multiplier for single height constraints with two different multipliers

Unfortunately you can't change the multiplier, but you can add two constraints, one with the landscape multiplier and another for the portrait multiplier.

Then in code you can activate/deactivate the constraints when the rotation occurs.

If you get an error in the storyboard just set the priority of one of the constraint to 999 or something under the other.

Animate NSLayoutConstraints multiplier and/or isActive state

Yes there is suppose that a view1 in storyboard has a width constraint to the main view (self.view in code) like this

  view1Width = view * 0.7 + constant 

instead of creating 2 constraints and switching between them by changing Active property ORRR [by deactivating current constraint with old multiplier and creating a new one with a new multiplier] leave it 1 constraint and play with it's constant

suppose i want to change view1 multiplier to be 0.9 instead of 0.7

I may do this

  self.view1Width.constant += self.view.frame.size.width * 0.2

same you do for subtraction

with this idea you haven't need to be stuck in how to animate active on/off but you still use

  self.view.layoutIfNeeded()


Related Topics



Leave a reply



Submit