添加导航控制器可以防止在根视图控制器中调用updateViewConstraints

时间:2014-05-15 14:03:06

标签: ios objective-c autolayout

我有一些代码来处理updateViewConstraints中我的根视图的旋转约束更改。它本身工作正常,但只要我添加一个导航控制器作为初始视图控制器,它就会在初始加载后完全停止调用该方法。

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

我把代码放在根视图控制器中,只是为了找出它破坏的原因,你只看到"更新视图约束"无论如何都叫一次。导航控制器是否有可以修复的东西?

编辑:可能有用的更多信息。根视图控制器是具有自定义集合视图布局的UICollectionViewDelegate。这是我认为可能与之相关的布局代码的唯一部分,但更改该值并不会影响该问题。

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
{
    return NO;
}

1 个答案:

答案 0 :(得分:7)

当设备旋转时,仅在window.rootViewController上调用updateViewContraints。因此,当您的UIViewController的子类是rootViewController时,您将获得日志消息。但是当它是UINavigationController的子视图控制器时,你没有。

您可以继承UINavigationController或UITabBarController,并添加updateViewConstraints的相同覆盖,看看我的意思。

我不完全理解为什么Apple在设备轮换时调用了rootViewController的updateViewContraints方法。我们开发人员应该使用Auto Layout的方法是使用[UIView setNeedsUpdateConstraints]方法告诉Auto Layout在下一个布局过程中调用[UIView updateConstraints],然后调用[UIViewController updateViewConstraints]。后一种方法允许视图控制器参与视图布局过程。

此外,[UIView updateConstraints]和[UIViewController updateViewConstraints]旨在添加或删除附加到视图的NSLayoutConstraint实例。约束本身提供了在布局传递发生时设置视图框架的解决方案。换句话说,如果已添加约束以使子视图居中,则每次更改边界并发生布局时,该约束将起作用。没有必要添加/删除/更新任何约束。

现在,如果你确实需要你的UIViewController子类在view.bounds改变时调用updateViewConstraints,你可以这样做:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    [self.view setNeedsUpdateConstraints];
}