IOS changes auto-layout restrictions when device rotates

I want to change layout constraints when the device rotates. My UIViewController consists of 2 UIViews , in the landscape they are horizontally aligned, and in the portrait they are vertically aligned.

It really works, in willAnimateRotationToInterfaceOrientation , I remove the required constraints and replace them with others in order to have the correct layout ...

But there are problems, during rotation, the auto layout begins to violate restrictions before calling willAnimateRotationToInterfaceOrientation , so where do we want to replace our restrictions when reorienting the device?

Another problem is performance, after a few turns the system does not violate more restrictions, but I have a huge drop in performance, especially in portrait mode ...

+43
ios objective-c autolayout nslayoutconstraint
Dec 06
source share
3 answers

In willRotateToInterfaceOrientation:duration: send setNeedsUpdateConstraints to any view that requires changing its restrictions.

Alternatively, subclass UIView . Register in your subclass for UIApplicationWillChangeStatusBarOrientationNotification . When you receive a notification, send setNeedsUpdateConstraints .

This sets the needsUpdateConstraints flag in the view. Before the system executes the layout (by sending layoutSubviews messages), it will send an updateConstraints message updateConstraints any view with the needsUpdateConstraints flag needsUpdateConstraints . Here you must change your restrictions. Subclass UIView and override updateConstraints to update your constraints.

+49
Apr 25 '13 at 7:31
source share

The post by Matthijs Hollemans has a very good explanation for auto-layout and rotation. You can find it here: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

Usually you need about 4 limits to correctly position your view. If my looks are of constant size, I prefer to embroider height and width. After that, you can use the restrictions of the leading and upper spaces to do whatever you want. For example, you can set IBOutlets for leading and upper space limits for your views:

 @interface ViewController : UIViewController { IBOutlet NSLayoutConstraint *_leadingSpaceConstraint; IBOutlet NSLayoutConstraint *_topSpaceConstraint; } 

Then drag control from the outlet to your restriction. Now you can directly change the view restriction from the code:

 _leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE; 

To commit changes you need to call:

 [self.view layoutIfNeeded]; 

And if you want to make it animated:

 [UIView animateWithDuration:0.25 animations:^{ [self.view layoutIfNeeded]; }]; 

I think it will work in willAnimateRotationToInterfaceOrientation, because you do not need to break any restrictions with this approach.

Example: You have two square images in portrait orientation, one below the other. For example, set the “leading surveillance space” limits to 20. Then set the “upper space to limit the supervisor” to 20 for the first view and 120 for the second. This will be our default setting.

Then, after the turn, you need to recount your limitations. Now set both upper limits to 20 and the leading limits to 20 and 120 respectively. Then commit the changes using layoutIfNeeded.

Hope this helps.

+13
Apr 25 '13 at 7:21
source share

override -(void) viewWillLayoutSubviews in the UIViewController to update your restrictions as shown below:

 -(void) viewWillLayoutSubviews { switch(self.interfaceorientation) { case UIInterfaceOrientationLandscapeLeft: break; case UIInterfaceOrientationLandscapeRight: break; case UIDeviceOrientationPortrait: break; case UIDeviceOrientationPortraitUpsideDown: break; } } 
+2
Feb 06 '13 at 8:12
source share



All Articles