Adding a Navigation Controller keeps updateViewConstraints from being called in root view controller

StackOverflow https://stackoverflow.com/questions/23680563

  •  23-07-2023
  •  | 
  •  

Domanda

I have a bit of code to handle constraint changes on rotation for my root view in updateViewConstraints. It works fine by itself, but as soon as I add a navigation controller as the initial view controller, it completely stops calling the method after the initial load.

-(void)updateViewConstraints
{
    [super updateViewConstraints];
    NSLog(@"Updating view constraints");
}

I put the code in for the root view controller just to find out why it was breaking and you only see "Updating view constraints" called once no matter what. Is there something being overridden by the navigation controller that can be fixed?

Edit: Some more info that might be of use. The root view controller is a UICollectionViewDelegate with a custom collection view layout. This is the only part of the layout code that I was thinking could possibly pertain to it, but changing the value doesn't affect the issue.

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
{
    return NO;
}
È stato utile?

Soluzione

updateViewContraints is being called only on the window.rootViewController when the device rotates. So when your subclass of UIViewController is the rootViewController, you get the log message. But when it is a child view controller of UINavigationController, you do not.

You can subclass UINavigationController or UITabBarController and add the same override of updateViewConstraints and see what I mean.

I do not fully understand why Apple has the rootViewController's updateViewContraints method invoked on device rotation. The way we developers are supposed to work with Auto Layout is to use [UIView setNeedsUpdateConstraints] method to tell Auto Layout to call [UIView updateConstraints] followed by [UIViewController updateViewConstraints] on the next layout pass. The latter method allows the view controller to participate in the view layout process.

Additionally [UIView updateConstraints] and [UIViewController updateViewConstraints] are intended to add or remove NSLayoutConstraint instances that are attached to the view. The constraints themselves provide the solution for setting the view's frame whenever the layout pass occurs. In other words, if a constraint has been added to center a subview, that constraint will work every time the bounds gets changed and layout occurs. It is not necessary to add/remove/update any constraint.

Now if you really do need your UIViewController subclass to call updateViewConstraints when its view.bounds changes, you can do this:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    [self.view setNeedsUpdateConstraints];
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top