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

Rotating whilst pushing a view controller onto a navigation controller does not correctly size pushed view controller

我看到一个非常奇怪的问题;就像用户旋转设备一样将视图控制器推入导航控制器会导致推送的视图控制器不会自动布局到导航控制器。

这是一个按下按钮触发 pushViewController 的演示:

[

首先,您可以看到按预期工作的推动(无旋转),然后在推动时出现混乱(旋转),最后在弹出时出现混乱(旋转)。

我特意做了我能想到的最简单的项目来测试这个,所以故事板是一个 viewcontroller,在导航控制器中有一个按钮,整个代码是:

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

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

我很难相信我在 iOS11 和 12(在 10 中没有出现)中遇到了一个迄今为止未被注意到的错误,但我真的不知道我能做什么如果在某些方面是我的错,这里错了。

有人以前看过这个或者对我在这里遗漏的内容有建议吗?

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

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

- (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];
        }
    }];
}

这似乎在转换到大小完成后正确调整了视图的大小。