在将视图控制器推到导航控制器上时旋转不能正确调整推入的视图控制器的大小

时间:2019-04-11 09:11:46

标签: ios objective-c autolayout

我看到一个非常奇怪的问题;就像用户旋转设备一样,将视图控制器推入导航控制器会使推入的视图控制器无法自动将其自身布置到导航控制器中。

这是一个演示,其中按下按钮会触发pushViewController:

[1]

首先,您可以看到推按预期的方式工作(不旋转),然后在推上弄乱(旋转),最后在弹出菜单上弄乱(旋转)。

我故意制作了一个我想想到的最简单的项目来进行测试,因此故事板是一个带有导航控制器中的按钮的视图控制器,整个代码是:

- (void)didTapButton:(id)sender
{
    UIViewController *viewController = [[UIViewController alloc] init];
    viewController.view.backgroundColor = [UIColor whiteColor];

    [self.navigationController pushViewController:viewController animated:YES];
}

我很难相信我在iOS11和12中遇到了迄今为​​止未注意到的错误(在10中不会发生),但我真的很茫然,如果我是我的错,我会在这里做错什么以某种方式。

有人以前看过这个吗,或者对我在这里缺少什么有建议?

1 个答案:

答案 0 :(得分:1)

我的猜测是,在转换为其他大小时,与推动有关的某种竞赛条件。当完成向新尺寸的过渡时,updateConstraints / needsLayout标志可能为NO(即,它已经认为在完成推送但尚未完成旋转之后就已经完全完成了对视图的布局)。我认为这是一个Apple Bug,如果您还没有的话,会报告它。

作为解决方法,您可以使用UINavigationController的子类并实现viewWillTransitionToSize:withTransitionCoordinator:,然后根据需要在[self.view setNeedsLayout]的完成代码块中抛出额外的[self.view setNeedsUpdateConstraints]coordinator animateAlongsideTransition:completion:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    } completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        UIView *topView = [self.topViewController view];
        // we should only need an additional layout if the topView's size doesn't match the size
        // we're transitioning to (otherwise it should have already beend layed out properly)
        BOOL needsAdditionalLayout = topView && CGSizeEqualToSize(topView.frame.size, size) == NO;
        if (needsAdditionalLayout) {
            // either of these two should do the trick
            [self.view setNeedsUpdateConstraints];
            // [self.view setNeedsLayout];
        }
    }];
}

这似乎可以在完成尺寸转换后正确调整视图的大小。