UIViewController更喜欢StatusBarHidden无法正常工作

Taz*_*Taz 43 objective-c uiviewcontroller ios ios7 ios7-statusbar

我正在尝试隐藏其中一个视图控制器的状态栏(以模态方式显示).当我呈现视图控制器时,状态栏将被隐藏,然后在被解雇时返回.

我已将以下代码添加到显示的视图控制器中

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

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

<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这应该是完成这项工作所需的全部内容.

我还使用自定义动画控制器来执行符合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;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*Liu 114

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

默认值为NO.

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

对于全屏显示的视图控制器,系统会忽略此属性的值.

因此,对于除正常全屏之外的任何presentationStyle(例如:UIModalPresentationCustom),如果要捕获状态栏,则必须设置此样式.要使用,您只需将其设置为YES正在显示的视图控制器:

toVC.modalPresentationCapturesStatusBarAppearance = YES;
Run Code Online (Sandbox Code Playgroud)

  • 只是注意到,如果模态表示样式是'当前上下文'到VC.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext,则这不起作用 (7认同)

mat*_*att 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];
}
Run Code Online (Sandbox Code Playgroud)

  • 我发现很难理解这是怎么回事.`prefersStatusBarHidden`应该由系统调用.它返回一个BOOL,你甚至没有捕获它(你只是扔掉它); 而你在系统后面调用它,所以系统什么也学不到.调用`setNeedsStatusBarAppearanceUpdate`非常重要,因为它会使_system_调用`prefersStatusBarHidden`并因此重新检索其结果. (2认同)