我正在尝试隐藏其中一个视图控制器的状态栏(以模态方式显示)。当我呈现视图控制器时,状态栏将被隐藏,然后在被解雇时返回。
我已将以下代码添加到呈现的视图控制器
- (BOOL)prefersStatusBarHidden
{
return YES;
}
我还将Info.plist文件中的密钥设置为以下内容:
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
根据我的理解,这应该是完成这项工作所需的全部内容。
我还使用自定义动画控制器来执行符合UIViewControllerAnimatedTransitioning
协议的呈现。在animateTransition:
实施中,我尝试手动调用prefersStatusBarHidden
,然后调用setNeedsStatusBarAppearanceUpdate
以确保正在进行调用,但状态栏仍然存在。
任何想法为什么会发生这种情况将不胜感激。我搜索过StackOverflow,但似乎没有人遇到过这个问题,所有接受的答案都是指我正在调用的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;
}
答案 0 :(得分:109)
在iOS7中,实际上有一个名为modalPresentationCapturesStatusBarAppearance
的UIViewController的新属性。 Apple iOS reference.
默认值为NO。
当您通过调用presentViewController:animated:completion:方法呈现视图控制器时,仅当呈现的控制器的modalPresentationStyle值为UIModalPresentationFullScreen时,状态栏外观控件才从呈现传送到呈现的视图控制器。通过将此属性设置为YES,即使呈现非全屏,也可以指定显示的视图控制器控件状态栏外观。
系统会忽略全屏显示的视图控制器的此属性值。
因此,对于除普通全屏外的任何presentationStyle(例如:UIModalPresentationCustom),如果要捕获状态栏,则必须设置 。要使用,您只需在显示的视图控制器上将其设置为YES
:
toVC.modalPresentationCapturesStatusBarAppearance = YES;
答案 1 :(得分:17)
我会猜测(受过教育,但仍然猜测)这是因为当您使用自定义转换执行呈现的视图控制器时,在iOS 7中,旧视图控制器仍然存在。因此它可能仍然有发言权。
您甚至可以在 prefersStatusBarHidden
中设置一个断点来查看;如果没有实现,你必须实现它。默认值为NO,因此如果查询,则可以解释您的结果。
如果我是对的,您需要实现旧视图控制器的prefersStatusBarHidden
来提供两个不同的答案,具体取决于它是否有presentedViewController
。
编辑我现在已经确认了这一点。它甚至比我想象的更糟糕;在我的测试中,第二个视图控制器的prefersStatusBarHidden
根本没有被调用。整个事情掌握在第一个视图控制器的手中。这是有道理的,因为正如我所说,第一个视图控制器永远不会消失;使用自定义演示动画时,第二个视图控制器从属于第一个视图控制器,因为第二个视图可以部分悬停在第一个视图上。
因此,您必须完全从第一个视图控制器驱动状态栏。您可以通过调用prefersStatusBarHidden
来调用[self setNeedsStatusBarAppearanceUpdate]
。你需要根据具体情况给出不同的答案。这可能有点棘手。这是一个简单的实现,但它可能无法涵盖所有情况:
// 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];
}
答案 2 :(得分:0)
您可以将其添加到info.plist
&#34;查看基于控制器的状态栏外观&#34;并将值设置为&#34;否&#34;
答案 3 :(得分:0)
如果它不起作用,并且您的UIViewController是UINavigationController中的子级,那么此代码可能是您的解决方案。
open override var prefersStatusBarHidden: Bool {
return topViewController?.prefersStatusBarHidden ?? super.prefersStatusBarHidden
}
基本上,UINavigationController使用它自己的 prefersStatusBarHidden 值,但就我而言,我想用其顶部视图控制器在层次结构中的属性覆盖它。