iOS change auto layout constraints when device rotates
In willRotateToInterfaceOrientation:duration:
, send setNeedsUpdateConstraints
to any view that needs its constraints modified.
Alternatively, make a UIView
subclass. In your subclass, register to receive UIApplicationWillChangeStatusBarOrientationNotification
. When you receive the notification, send yourself setNeedsUpdateConstraints
.
This sets the needsUpdateConstraints
flag on the view. Before the system performs layout (by sending layoutSubviews
messages), it sends an updateConstraints
message to any view that has the needsUpdateConstraints
flag set. This is where you should modify your constraints. Make a UIView
subclass and override updateConstraints
to update your constraints.
There is very good explanation of auto-layout and rotations in Matthijs Hollemans post. You can find it here: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
Usually, you need about 4 constraints to correctly position your view. If my views have constant size i prefer to pin height and width. After that you can use Leading and Top space constraints to do whatever you want. For example, you can set IBOutlets for leading and top space constraints for your views:
@interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *_leadingSpaceConstraint;
IBOutlet NSLayoutConstraint *_topSpaceConstraint;
}
Then control-drag from outlet to your constraint. Now you can directly change your view constraint from code:
_leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE;
To commit your changes you need to call:
[self.view layoutIfNeeded];
And if you want to do it animated:
[UIView animateWithDuration:0.25
animations:^{
[self.view layoutIfNeeded];
}];
I think it will work in willAnimateRotationToInterfaceOrientation, because you don't need to break any constraints with this approach.
Some example: You have two square view in portrait orientation, one under another. Set their "leading space to superview" constraints to 20, for example. Then set "top space to superview constraint" to 20 for first view and to 120 for second. It will be our default setup.
Then, after rotation you need to recalculate your constraints. Now set both of top constraints to 20, and leading constraints to 20 and 120 respectively. Then commit changes with layoutIfNeeded.
I hope it will help.
override -(void) viewWillLayoutSubviews
in your UIViewController
to update your constraints as below code:
-(void) viewWillLayoutSubviews {
switch(self.interfaceorientation)
{
case UIInterfaceOrientationLandscapeLeft:
break;
case UIInterfaceOrientationLandscapeRight:
break;
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
}
}