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
What Are Sprite Kit'S "Category Mask" and "Collision Mask"
Allow Only Numbers For Uitextfield Input
Subclass Uiapplication With Swift
Iphone Smooth Sketch Drawing Algorithm
Undocumented Nsurlerrordomain Error Codes (-1001, -1003 and -1004) Using Storekit
Adding a Closure as Target to a Uibutton
How to Reload Data in a Tableview from a Different Viewcontroller in Swift
Error: Error Installing Cocoapods: Error: Failed to Build Gem Native Extension
Detecting a Point in a Mkpolygon Broke with iOS7 (Cgpathcontainspoint)
Method 'Application:Openurl:Options:' Is Not Called
Navigation Bar With Uiimage For Title
Ios7 Uitextview Contentsize.Height Alternative
Detect Current Device With Ui_User_Interface_Idiom() in Swift
iOS 7 Tableview Like in Settings App on iPad