iOS隐藏和取消隐藏状态栏不能正确移动子视图

我有一个自定义视图控制器,可以包含两个子视图控制器.当设备处于纵向时,其中一个控制器的视图可见.当设备处于横向时,其他控制器的视图可见.但是,当横向方向视图可见时,状态栏将缩回以为特定视图腾出更多空间.设备重新进入纵向模式后,状态栏将取消显示.这是自定义视图控制器显示在UINavigationController中.

我的问题是,当状态栏的可见性发生变化时,我的子视图无法正确调整.当您以不同方向转动设备时,最终会出现较大的间隙和/或重叠,如下图所示:

正如您所看到的,它最初很好(纵向),但是当设备转动时,状态栏就会出现白色间隙.当设备转回纵向时,UINavigationController的导航栏会被状态栏调出并重叠,导航栏与其下方视图之间会出现间隙.如果您可以非常快速地从一个横向方向旋转180度到相反的横向方向,则间隙消失并且看起来很好.

下面的方法属于自定义视图控制器,并在willAnimateRotationToInterfaceOrientation中调用:duration :(显然用于处理旋转事件)和viewDidAppear :(用于处理从导航堆栈中的上一个视图控制器推入的视图时).

- (void)cueAnimationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation fromViewDidAppear:(BOOL) fromViewDidAppear
{
    // Fading animation during orientation flip.
    // Make sure its not already animating before trying.
    BOOL barHidden =  [UIApplication sharedApplication].statusBarHidden;
    if (!isAnimating) {
        BOOL alreadyGoodGrid = (UIInterfaceOrientationIsLandscape(interfaceOrientation) && curView == self.gridViewController.view);
        BOOL alreadyGoodTable = (UIInterfaceOrientationIsPortrait(interfaceOrientation) && curView == self.tableViewController.view);
        if ((alreadyGoodGrid && barHidden) ||
            (alreadyGoodTable && !barHidden)) {
            // If views are the way they should be for this orientation. Don't do
            // anything.
            return;
        }
        isAnimating = YES;
        UIView *nextView;
        // Get starting orientation. This will determine what view goes on top
        if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
            nextView = self.gridViewController.view;
        else
            nextView = self.tableViewController.view;

        if (nextView == self.tableViewController.view)
        {
            if (!alreadyGoodTable)
            {
                self.tableViewController.view.alpha = 0.0;
                [self.view bringSubviewToFront:self.tableViewController.view];
            }
            // Unhide the bar for the table view
            [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
        }
        else // gridViewController
        {
            if (!alreadyGoodGrid)
            {
                self.gridViewController.view.alpha = 0.0;
                [self.view bringSubviewToFront:self.gridViewController.view];
            }
            // Hide the bar for the grid view
            [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
        }
        [UIView animateWithDuration:0.4
                              delay: 0.0
                            options: UIViewAnimationOptionAllowUserInteraction
                         animations:^{
                             if (nextView == self.tableViewController.view) {
                                 self.tableViewController.view.alpha = 1.0;
                             }
                             else {
                                 self.gridViewController.view.alpha = 1.0;
                             }                             
                         }
                         completion:^(BOOL finished) {
                             if (nextView == self.tableViewController.view) {
                                 curView = self.tableViewController.view;
                             }
                             else {
                                 curView = self.gridViewController.view;
                             }
                             isAnimating = NO;
                         }];
    }
}

非常感谢任何可以花时间看这个的人.

最佳答案 很多人似乎都有这个问题,就像我一样,还有其他Q / A线程,你应该搜索它 – 我可能永远找不到神奇的答案.在某些情况下,您可能会尝试“修复”问题的一个问题是当您将条形图可见性更改为(重新)显示状态栏时:

>隐藏导航栏.
>取消隐藏状态栏.
>取消隐藏导航栏.

或者,如果隐藏状态栏,则隐藏,隐藏,取消隐藏.

有时人们发现在取消隐藏导航栏之前需要稍微延迟 – 所以在异步调度块中执行此操作以在下一个runloop上运行.就像是:

dispatch_async(dispatch_get_main_queue(), ^{
        [self.navigationController setNavigationBarHidden:NO animated:NO];
});
点赞