12

iOS 7 过渡指南给出了一个很好的提示,如何在使用中UIStatusBarStyle动态更改UIViewController

- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleDefault;
}

和...一起[self setNeedsStatusBarAppearanceUpdate];

这在单视图应用程序中运行良好。但是,我现在正在尝试将UIStatusBarStyle模式视图中的 更改为UIStatusBarStyleLightContent. 有一个MainViewControllerwhich 连接到ModalViewController,它本身嵌入在 a 中NavigationController。已将其ModalViewController委托设置为MainViewController

我尝试在该类中与以下方法一起调用,但没有效果[self setNeedsStatusBarAppearanceUpdate];ModalViewController

// In ModalViewController.m
- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

我还尝试在显示模式视图时调用带有条件的方法[self setNeedsStatusBarAppearanceUpdate];以返回- 但这也没有效果。MainViewControllerprepareForSegue: sender:- (UIStatusBarStyle)preferredStatusBarStyle {}UIStatusBarStyleLightContent

如何更改模式视图中的 UIStatusBarStyle?

编辑:更新后:我需要提到的ModalViewController是嵌入在NavigationController带有NavigationBar. 设置为隐藏到NavigationBar上述调用[self setNeedsStatusBarAppearanceUpdate];inModalViewController工作正常。但不是在酒吧可见时。

4

9 回答 9

29

您需要一个以全屏显示的 ViewController 来返回适当的状态栏信息。在您的情况下:包含 ModalViewController 的 NavigationController 需要实现preferredStatusBarStyle并返回UIStatusBarStyleLightContent

setNeedsStatusBarAppearanceUpdate仅当视图控制器返回的值实际发生变化时才需要调用。当视图控制器第一次出现时,无论如何都会查询它们。

于 2013-09-29T04:19:10.947 回答
25

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

任何想进一步了解状态栏控件的人都不应忽略UIViewController 管理状态栏

2015-11-06 更新:

并确保您已UIViewControllerBasedStatusBarAppearanceiOS Keys中进行了设置

2018.04.09 更新:

我注意到导航控制器中的 viewController 可能无法prefersStatusBarHidden在 iOS 10.0 - 10.2 中调用。自定义您的 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

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

于 2015-03-18T11:24:25.973 回答
11

完成这项工作的关键是只有全屏视图控制器才能决定状态栏的样式。

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

确保将情节提要场景中的类引用从 UINavigationController 更改为子类(例如下面示例中的 MyNavigationController)。

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

@interface MyNavigationController : UINavigationController

@end

@implementation MyNavigationController

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

@end
于 2013-10-16T18:14:42.730 回答
6

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

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

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

于 2015-11-27T01:37:27.023 回答
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;
}
于 2013-12-16T14:24:58.670 回答
1

似乎应用程序脱离了最顶层 viewController 的 statusBarStyle。因此,如果您在当前视图控制器之上添加另一个视图控制器,它现在会从新视图控制器中获取提示。

于 2013-10-15T19:43:54.170 回答
1

这对我有用:

  1. 设置View controller-based status bar appearanceNO
  2. 将状态栏样式设置为UIStatusBarStyleLightContent(只需复制该值)
  3. 在 appDelegate 中使用[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

希望它有所帮助(参考:ios7 状态栏在模态视图上变回黑色?

于 2015-06-30T09:43:01.777 回答
0

只需查看您的应用程序的rootViewController 是否需要覆盖 -(UIStatusBarStyle)preferredStatusBarStyle 方法

于 2014-01-15T10:01:24.550 回答
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,我只是觉得这很方便。

于 2014-04-01T01:06:28.113 回答