简体   繁体   中英

Correct way to programmatically update constraints when the device orientation changes?

I'm using storyboard and autolayout , and setting the constraints in IB as IBOutlet in the corresponding view controller. I'm reading several posts regarding how to update the constraints to be different in portrait and in landscape but I'm still not sure of how should I do this:

  1. Should I set the new constraints in -viewWillTransitionToSize:withTransitionCoordinator: method, or in updateViewConstraints method?
  2. When the new constraints are set, should I call [self.view setNeedsUpdateConstraints]; , or layoutIfNeeded , or setNeedsLayout ?
  3. How should I update, for example, the constant of a certain constraint:

    self.myConstraint.constant = 30.0

or doing:

[self.view removeConstraint:self.passwordViewHeight];

self.passwordViewHeight = [NSLayoutConstraint constraintWithItem:self.passwordView
                                                      attribute:NSLayoutAttributeHeight
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:nil
                                                      attribute:NSLayoutAttributeNotAnAttribute
                                                     multiplier:1.0
                                                       constant:34.0];

[self.view addConstraint:self.passwordViewHeight];

Thanks in advance

Orientation change be detected using the method viewWillTransitionToSize. This method will be called when the device orientation is about to change.

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator (id<UIViewControllerTransitionCoordinator>)coordinator{
      //change constraints
}

Alternatively, if you want to change the constraints after the orientation changes, use the coordinator object's animateAlongsideTransition method in the viewWillTransitionToSize method.

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        //change constraints
    }];
}

The best way would be to change the constant instead of removing the constraint and recreating it again. Just adding or subtracting from the constant is much faster in the long run as well. What you would want to do is something like:

[self.view layoutIfNeeded];
self.myConstraint.constant = 30.0;
[self.view layoutIfNeeded];

It is recommended that you call layoutIfNeeded before and after you change the constant as well. This is because you may have some constraint that has not yet been done and will do so then, before you change more constraints.

The best idea will be use Size Classes in Interface Builder to achieve autorotation change.

https://www.codefellows.org/blog/size-classes-with-xcode-6-one-storyboard-for-all-sizes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM