如何使用导航栏在模态视图中更改iOS 7中的UIStatusBarStyle?

时间:2013-09-25 07:41:27

标签: ios ios7 modalviewcontroller statusbar

iOS 7 Transition Guide提供了一个很好的提示,如何使用

UIStatusBarStyle中动态更改UIViewController
- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleDefault;
}

[self setNeedsStatusBarAppearanceUpdate];

一起

这在单个视图应用程序中工作正常。但是,我现在正尝试将模态视图中的UIStatusBarStyle更改为UIStatusBarStyleLightContent。有一个MainViewControllerModalViewController相邻,NavigationController本身嵌入ModalViewControllerMainViewController已将其委托设置为[self setNeedsStatusBarAppearanceUpdate];

我尝试在ModalViewController中调用// In ModalViewController.m - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } 以及该类中的以下方法而不起作用:

[self setNeedsStatusBarAppearanceUpdate];

我还尝试在MainViewController方法prepareForSegue: sender:- (UIStatusBarStyle)preferredStatusBarStyle {}调用UIStatusBarStyleLightContent条件,ModalViewController条件,当呈现模态视图时返回NavigationController - 但是也没有任何影响。

如何在模态视图中更改UIStatusBarStyle?

编辑:发布更新:我需要提及的是NavigationBar嵌入NavigationBar [self setNeedsStatusBarAppearanceUpdate];。将ModalViewController设置为隐藏到{{1}} {{1}}以上的{{1}}调用工作正常。但是当酒吧可见时不会。

9 个答案:

答案 0 :(得分:28)

您需要一个在Fullscreen中显示的ViewController才能返回相应的状态栏信息。在您的情况下:包含ModalViewController的NavigationController需要实现preferredStatusBarStyle并返回UIStatusBarStyleLightContent

只有在视图控制器返回的值实际发生更改时,才需要调用setNeedsStatusBarAppearanceUpdate。首次显示视图控制器时,无论如何都会查询它们。

答案 1 :(得分:24)

我们应该注意到非全屏modalVC CAN 使用modalPresentationCapturesStatusBarAppearance来控制statusBar样式。

任何想要了解有关状态栏控件的更多信息的人都不应忽略UIViewController Managing the Status Bar

2015-11-06更新:

并确保您已设置iOS Keys

中描述的UIViewControllerBasedStatusBarAppearance

更新于2018.04.09:

我注意到navController中的viewController可能无法通过iOS 10.0 - 10.2调用prefersStatusBarHidden。自定义您的navigationController以确保

@implementation YourCustomNavController
//for iOS 10.0 - iOS 10.2
- (BOOL)prefersStatusBarHidden {
    UIViewController *childVC = [self childViewControllerForStatusBarHidden];
    if (childVC) {
        return [childVC prefersStatusBarHidden];
    }
    return [super prefersStatusBarHidden];
}
@end

任何想进入更深层次的人都可以使用Hopper或IDA Pro深入了解UIKit +[UIViewController _currentStatusBarStyleViewController]。它可以帮助您解决这些类型的错误。

答案 2 :(得分:11)

使这项工作的关键是只有全屏视图控制器才能决定状态栏的风格。

如果您正在使用导航控制器并希望在每个视图控制器的基础上控制状态栏,您将需要子类化UINavigationController并实现preferredStatusBarStyle,以便它返回topViewController的首选项。

确保将故事板场景中的类引用从UINavigationController更改为子类(例如下例中的MyNavigationController)。

(以下对我有用。如果您的应用程序是基于TabBar的,您可能希望通过继承UITabBarController来做类似的事情,但我还没有尝试过。)

@interface MyNavigationController : UINavigationController

@end

@implementation MyNavigationController

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return self.topViewController.preferredStatusBarStyle;
}

@end

答案 3 :(得分:6)

要更改嵌入ViewController的UINavigationController的状态栏而不继承UINavigationController,请使用:

navigationController?.navigationBar.barStyle = .Black // to make the status bar text white

。黑色会使文本变为白色(状态栏和视图的标题),而.Default会有黑色标题和状态栏。

答案 4 :(得分:2)

我有一个侧面菜单/显示控制器(SWRevealController),它总是成为状态栏查询的根控制器。覆盖childViewControllerForStatusBarStyle让我将查询重新路由到最前面的控制器。

/**
 This view is always considered the topmost for status bar color queries.
 Pass the query along to what we're showing in front.
 */
- (UIViewController *)childViewControllerForStatusBarStyle
{
    UIViewController *front = self.frontViewController;
    if ([front isKindOfClass:[UINavigationController class]])
        return ((UINavigationController*)front).topViewController;
    else
        return front;
}

答案 5 :(得分:1)

似乎应用程序关闭了最顶层viewController的statusBarStyle。因此,如果您在当前的ViewController之上添加另一个viewController,它现在可以从新的viewController获取它的提示。

答案 6 :(得分:1)

这对我有用:

  1. View controller-based status bar appearance设为NO
  2. 将状态栏样式设置为UIStatusBarStyleLightContent(只需复制该值)
  3. 在appDelegate中使用[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
  4. 希望它有所帮助(参考:ios7 status bar changing back to black on modal views?

答案 7 :(得分:0)

如果您的应用 rootViewController需要覆盖 - (UIStatusBarStyle)preferredStatusBarStyle方法

,请查看

答案 8 :(得分:0)

以上所有工作。然而,有时候我发现在故事板中改变每个实例的底部真的很痛苦......所以这里有一些对我有用的东西也涉及子类化。

首先创建子类:

@interface HHNavLightColorBarController : UINavigationController

@end

@implementation HHNavLightColorBarController

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}
@end

然后使用Objective-C的魔力和一点< objc / runtime.h>

当你有一个视图控制器的引用并且你呈现它时:

UINavigationController *navVC = ...; // Init in your usual way
object_setClass(navVC, [HHNavLightColorBarController class]);
[self presentViewController:nav animated:YES completion:^{
    NSLog(@"Launch Modal View Controller");
}];

有时它看起来有点不太干扰。您甚至可以创建一个类别来检查您的kindOfClass是否为导航控制器并自动为您执行此操作。无论如何,jaetzold的答案就在上面,我发现这很方便。