UIViewController的偏好状态栏隐藏不工作

我试图让我的视图控制器之一的状态栏被隐藏(当模态显示)。 当我呈现视图控制器时,状态栏将被隐藏,然后被解散时返回。

我已经将下面的代码添加到呈现的视图控制器

- (BOOL)prefersStatusBarHidden { return YES; } 

我还将Info.plist文件中的密钥设置为以下内容:

 <key>UIViewControllerBasedStatusBarAppearance</key> <true/> 

根据我的理解,这应该是完成这项工作所需的一切。

我也使用自定义animation控制器来执行符合UIViewControllerAnimatedTransitioning协议的呈现。 在animateTransition:实现中,我试图手动调用prefersStatusBarHidden ,后面跟着setNeedsStatusBarAppearanceUpdate以确保调用正在进行,但状态栏仍然存在。

任何想法,为什么发生这将不胜感激。 我已经searchStackOverflow,但似乎没有人有这个问题,所有接受的答案指的是调用setNeedsStatusBarAppearanceUpdate ,我已经在做。

编辑 – 下面的代码现在似乎工作正常

 - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { if (self.isPresenting) { UIView *containerView = [transitionContext containerView]; UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; toViewController.view.frame = containerView.frame; [containerView addSubview:toViewController.view]; // Ask the presented controller whether to display the status bar [toViewController setNeedsStatusBarAppearanceUpdate]; [UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{ toViewController.view.alpha = 1.0f; fromViewController.view.alpha = 0.0f; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } else { // do the reverse UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; [UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{ toViewController.view.alpha = 1.0f; fromViewController.view.alpha = 0.0f; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; // Once dismissed - ask the presenting controller if the status bar should be presented [toViewController setNeedsStatusBarAppearanceUpdate]; }]; } } .... // PresentingController.m - (BOOL)prefersStatusBarHidden { if (self.presentedViewController) { return YES; } return NO; } // PresentedController.m - (BOOL)prefersStatusBarHidden { return YES; } 

在iOS7中,实际上有一个名为modalPresentationCapturesStatusBarAppearance UIViewController的新属性。 苹果iOS参考。

默认值是NO。

当您通过调用presentViewController:animated:completion:方法呈现视图控制器时,只有当呈现的控制器的modalPresentationStyle值为UIModalPresentationFullScreen时,状态栏外观控件才会从呈现转移到呈现的视图控制器。 通过将此属性设置为YES,即使呈现非全屏,也可以指定呈现的视图控制器控制状态栏外观。

系统忽略全屏显示的视图控制器的该属性值。

因此,对于除正常全屏之外的任何presentationStyle(例如:UIModalPresentationCustom),如果要捕获状态栏,则必须设置此项。 要使用,您所要做的就是在正在呈现的视图控制器上将其设置为YES

 toVC.modalPresentationCapturesStatusBarAppearance = YES; 

我会猜测(这是受过教育的,但仍是一个猜测),这是因为当你使用自定义转换做一个呈现的视图控制器时,在iOS 7中, 旧的视图控制器仍然在那里 。 所以它可能还是有话说的。

你甚至可以在它的 prefersStatusBarHidden放置一个断点来查看; 如果没有实现,你必须实现它。 默认值是NO,所以如果咨询,这将解释你的结果。

如果我是对的,你需要实现旧的视图控制器的prefersStatusBarHidden来给出两个不同的答案,这取决于它是否有一个prefersStatusBarHidden

编辑我已经证实了这一点。 这比我想象的还要糟糕。 在我的testing中,第二个视图控制器的prefersStatusBarHidden根本没有被调用。 整个事情在第一个视图控制器手中。 这是有道理的,因为,正如我所说,第一个视图控制器永远不会消失; 使用自定义演示animation,第二个视图控制器从属于第一个视图,因为第二个视图可以部分hover在第一个视图上。

因此,你将不得不从第一个视图控制器完全驱动状态栏。 你可以通过调用[self setNeedsStatusBarAppearanceUpdate]来调用它的prefersStatusBarHidden 。 您需要根据具体情况给出不同的答案。 这可能有点棘手。 这是一个简单的实现,但可能不包括所有的情况:

 // ViewController1: -(void)setHide:(NSNumber*)yn { self->hide = [yn boolValue]; // a BOOL ivar [self setNeedsStatusBarAppearanceUpdate]; } -(BOOL)prefersStatusBarHidden { return self->hide; } - (IBAction)doButton:(id)sender { self->hide = YES; [self setNeedsStatusBarAppearanceUpdate]; [self presentViewController:[ViewController2 new] animated:YES completion:nil]; } // ========== // ViewController2: - (IBAction)doButton:(id)sender { [self.presentingViewController setValue:NO forKey:@"hide"]; [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; }