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

Posted

技术标签:

【中文标题】iOS 7:模态视图控制器状态栏颜色错误,但普通视图控制器正确【英文标题】:iOS 7: modal view controller status bar is wrong color but normal view controllers are correct 【发布时间】:2014-01-04 08:03:49 【问题描述】:

我在 ios7 中遇到了一个问题,普通 UINavigationController 推送视图控制器的状态栏文本颜色与 UINavigationController 导航栏颜色正确(浅灰色,几乎是白色,因此状态栏文本为黑色)。但是,当使用-presentViewController:animated:completion: 呈现“模态”视图控制器时,状态栏文本颜色将变为白色,并且很难看到导航栏的颜色。导航栏颜色在整个应用程序中始终相同,并且不会因每个视图控制器而改变。每次-presentViewController 调用都会发生这种情况。

“基于视图控制器的状态栏外观”设置为 YES。

我不知道该看什么来尝试解决这个问题。

【问题讨论】:

确实要解决的真正问题是模式弹出窗口上不断变化的背景颜色?更改状态栏文本颜色并不能解决根本问题 这里讨论了一些解决方案,但它们有点老套:blog.ijasoneverett.com/2013/09/… 【参考方案1】:

将 YourModalViewControler.modalPresentationCapturesStatusBarAppearance 设置为 YES 并将“基于控制器的状态栏外观”设置为 YES。

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

然后覆盖preferredStatusBarStyle

- (UIStatusBarStyle)preferredStatusBarStyle 
    return TheStyleYouWant;

【讨论】:

谢谢!不知何故,modalPresentationCapturesStatusBarAppearance 属性完全从我身边经过,直到我尝试这个,我才知道为什么我无法正确显示我的模态状态栏。 为我工作,但在呈现 viewController 之前设置 modalPresentationCapturesStatusBarAppearance = true【参考方案2】:

导航控制器根据其导航栏的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];

【讨论】:

谢谢!完美运行。【参考方案3】:

您可以在导航控制器类中重新定义 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 调用并没有改变模态呈现的 viewControllers 的结果。我会再试一次以确保。谢谢! 您尝试过 UIStatusBarStyleDefault 吗?我认为这是一个或另一个 UIStatusBarStyleLightContent 这并不能解决所描述的问题。只要应用程序使用 VC 控制的状态栏外观,preferredStatusBarStyle 方法就不会被模态显示的屏幕调用,但在其他情况下效果很好。这仍然在 iOS 7.1 中发生。【参考方案4】:

我只是想出了如何做到这一点。我遇到了完全相同的问题,看起来它就像一个魅力!

您需要做的第一件事是将项目的 .plist 文件中的属性更改为 NO。属性为:“查看基于控制器的状态栏外观”。如果该属性不存在,请不要犹豫,按照我刚刚写给您的内容添加一个新属性(不带引号)。

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

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

如果您希望状态栏的文本为白色或

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

如果您希望状态栏的文本为黑色。

就是这样!

【讨论】:

【参考方案5】:

这行得通。但我对此并不满意,因为它有点 hacky。我认为 preferredStatusBarStyle 不被称为模态视图是一个错误。会问苹果。

- (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];

【讨论】:

@Banana 添加[self setNeedsStatusBarAppearanceUpdate].【参考方案6】:

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

【讨论】:

【参考方案7】:

我遇到了和你一样的问题。 info.plist 是正确的,并且在其他任何地方都正确调用了 preferredStatusBarStyle。但不是在我的模态视图中。那是因为preferredStatusBarStyle 被发送到导航控制器。所以我创建了一个 UINavigationController 的子类,它将 preferredStatusBarStyle 传递给它正在呈现的视图控制器,瞧,一切都再次正常运行

【讨论】:

【参考方案8】:

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

这可能不适合你,但它适合我,原因如下:

    无论如何,我的模态对话框都有一个导航栏(尽管它不用于导航;它只是用于保存或关闭结果。 如上所述,状态栏颜色已在applicationDidFinishLaunching 中在应用程序范围内定义,并且具有自定义颜色。

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

【讨论】:

【参考方案9】:

我的解决方案:

newViewController.modalPresentationStyle = .fullScreen

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

【讨论】:

以上是关于iOS 7:模态视图控制器状态栏颜色错误,但普通视图控制器正确的主要内容,如果未能解决你的问题,请参考以下文章

模态视图的 iOS7 状态栏字体颜色

iOS 7 - 模态变化的状态栏颜色?

模态关闭后,键盘显示错误的颜色 - iOS

iOS 7 中 UIActivityViewControllers 的模态状态栏和导航栏文本颜色

状态栏文本颜色iOS 7 [重复]

iOS 7:如何在一个视图控制器中将状态栏文本颜色更改为白色,在第二个视图控制器中更改为黑色?