iOS 7:模态视图控制器状态栏颜色错误,但普通视图控制器是正确的。

21
我在iOS7中遇到一个问题,普通的UINavigationController推送的视图控制器具有正确的状态栏文本颜色,与UINavigationController导航栏颜色相同(是浅灰色,几乎是白色,所以状态栏文本是黑色)。然而,当使用-presentViewController:animated:completion:呈现"模态"视图控制器时,状态栏文本颜色会更改为白色,并且由于导航栏的颜色非常难以看清。导航栏颜色在整个应用程序中始终保持不变,对于每个视图控制器都不会更改。这在每个-presentViewController调用上都会发生。
“基于视图控制器的状态栏外观”设置为YES。
我不确定要查看什么来尝试解决这个问题。

当然要解决的真正问题是在模态弹出窗口上更改背景颜色?更改状态栏文本颜色无法解决根本问题。 - HughHughTeotl
这篇文章讨论了一些解决方案,但它们有点hackish:http://blog.ijasoneverett.com/2013/09/ios-7-bugs-the-status-bar-and-modal-view-controllers/ - HughHughTeotl
9个回答

18

将 YourModalViewController.modalPresentationCapturesStatusBarAppearance 设置为 YES,并保持 "View controller-based status bar appearance" 为 YES。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.modalPresentationCapturesStatusBarAppearance = YES;
    ....
}

然后覆盖preferredStatusBarStyle

- (UIStatusBarStyle)preferredStatusBarStyle {
    return TheStyleYouWant;
}

谢谢!不知何故,modalPresentationCapturesStatusBarAppearance属性完全没有引起我的注意,直到我尝试了这个方法,我才明白为什么我不能正确地显示模态状态栏。 - Karl White
对我有用,但在呈现视图控制器之前设置 modalPresentationCapturesStatusBarAppearance = true - zgluis

15
导航控制器根据其导航栏的barStyle属性来决定使用浅色或深色内容。默认值UIBarStyleDefault表示导航栏具有浅色,并且状态栏将具有深色内容。将此属性更改为UIBarStyleBlack实际上并不使导航栏变黑(导航栏的颜色仍使用barTintColor设置),但它告诉它具有深色。然后,导航控制器会决定,由于导航栏是深色的,它应将状态栏内容设置为浅色。
看起来你的主导航控制器(用于推送事物)确实在某个地方将barStyle设置为UIBarStyleBlack。您必须对模态呈现的导航控制器执行相同操作,如下所示:
UINavigationController *newViewController = [[UINavigationController alloc] initWithRootViewController:modalViewController];
newViewController.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
[self presentViewController:newViewController animated:YES completion:nil];

谢谢!完美运作。 - Mike Demidov

2

这个可以用,但我不是很满意,因为它有点hacky。我认为preferredStatusBarStyle在模态视图中没有被调用是一个bug。我会向苹果提问。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    [self setNeedsStatusBarAppearanceUpdate];
}


- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
    [self setNeedsStatusBarAppearanceUpdate];
}

@香蕉 添加 [self setNeedsStatusBarAppearanceUpdate] - meaning-matters

2
你可以在导航控制器类中重新定义preferredStatusBarStyle方法。
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
// or UIStatusBarStyleBlackOpaque, UIStatusBarStyleBlackTranslucent, or UIStatusBarStyleDefault

}

同时,您也可以定义一个“视图加载方法”来设置您想要的自定义颜色。

- (void) viewDidLoad
{
    UIColor *barColor = [UIColor whitecolor];

    UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0.f, -20.f, 320.f, 64.f)];
    colorView.opaque = NO;
    colorView.alpha = .5f;
    colorView.backgroundColor = barColor;

    self.navigationBar.barTintColor = barColor;
    self.navigationBar.tintColor = [UIColor whiteColor];
    [self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];

    /*self.navigationController.navigationBar.barTintColor = [UIColor blackColor];
     self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
     [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]}];
     self.navigationController.navigationBar.translucent = NO;*/

    [self.navigationBar.layer insertSublayer:colorView.layer atIndex:0];

}

我需要再试一次,因为已经过了几天,但是当我尝试过时,preferredStatusBarStyle调用并没有改变模态呈现的视图控制器的结果。我会再试一次以确保。谢谢! - chadbag
你尝试过使用UIStatusBarStyleDefault吗?我认为它要么是UIStatusBarStyleLightContent。 - user2163433
这并不能解决所描述的问题。只要应用程序使用VC控制的状态栏外观,preferredStatusBarStyle方法将永远不会为模态显示的屏幕调用,但在其他情况下效果很好。这在iOS 7.1中仍然存在。 - mcsheffrey

2

我刚刚弄清楚如何做到这一点。我遇到了完全相同的问题,看起来它确实像一个魅力!

第一件事是在您的项目的 .plist 文件中更改一个属性为 NO。该属性是:"View controller-based status bar appearance"。如果该属性不存在,请毫不犹豫地添加一个与我刚刚写给您的完全相同的新属性(不带引号)。

第二件事是在每个视图控制器的 viewDidLoad 方法中添加:

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

如果您想让状态栏的文本为白色或其他颜色,请按照以下步骤操作:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

如果您想让状态栏的文本显示为黑色。
就这样!
需要注意的是,请保留HTML标签。

2

在您的info.plist中,将UIViewControllerBasedStatusBarAppearance设置为NO


1

我遇到了和你一样的问题。info.plist是正确的,在其他地方也正确调用了preferredStatusBarStyle。但是在我的模态视图中不能正常工作。这是因为preferredStatusBarStyle被发送到了导航控制器。所以我创建了一个UINavigationController的子类,将preferredStatusBarStyle传递给它正在呈现的视图控制器,然后,哇,一切都恢复正常了。


0

我的解决方案:

newViewController.modalPresentationStyle = .fullScreen

默认情况下,UINavigationController决定状态栏的样式并覆盖所有子视图控制器的样式。然而,当模态视图控制器全屏时,它的方法preferredStatusBarStyle会被调用。


0

在查看了这里和其他答案提供的所有答案后,我发现对我有效的唯一解决方案是为我模态呈现的视图控制器创建一个空的导航栏

这可能对您不起作用,但对我来说有以下原因:

  1. 我的模态对话框已经有了一个导航栏(尽管它不用于导航;它只是用于保存或关闭结果)。
  2. 状态栏颜色已经在上面讨论的applicationDidFinishLaunching中全局定义,并且具有自定义颜色。

从工程角度来看,拥有一个实际上什么也不做的导航控制器有点烦人,但如果没有它,我将无法解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接