preferredStatusBarStyle不被调用
我跟着这个线程来覆盖-preferredStatusBarStyle ,但它不被调用。 有什么select,我可以改变启用它?  (我在我的项目中使用XIB。) 
可能的根本原因
我有同样的问题,并发现这是因为我没有在我的应用程序窗口中设置根视图控制器。
 我在其中实现了preferredStatusBarStyle的UIViewController在UITabBarController ,它控制了屏幕上的视图的外观。 
 当我设置根视图控制器指向此UITabBarController ,状态栏更改开始正常工作,并按预期方式(并调用preferredStatusBarStyle方法)。 
 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // other view controller loading/setup code self.window.rootViewController = rootTabBarController; [self.window makeKeyAndVisible]; return YES; } 
替代方法(在iOS 9中弃用)
 或者,您可以根据自己的背景颜色,在每个视图控制器中根据需要调用以下其中一种方法,而不必使用setNeedsStatusBarAppearanceUpdate : 
 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 
要么
 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; 
 请注意,如果使用此方法,则还需要在plist文件中将UIViewControllerBasedStatusBarAppearance设置为NO 。 
对于任何使用UINavigationController的人:
  UINavigationController不会将preferredStatusBarStyle调用转发到其子视图控制器。 相反,它pipe理着自己的状态,因为它应该在状态栏所在的屏幕顶部绘制,所以应该对它负责。 因此,在导航控制器内的VC中实现preferredStatusBarStyle将不会执行任何操作 – 它们将永远不会被调用。 
 窍门是UINavigationController用来决定返回什么UIStatusBarStyleDefault或UIStatusBarStyleLightContent 。 它基于它的UINavigationBar.barStyle 。 默认( UIBarStyleDefault )导致在黑暗的前景UIStatusBarStyleDefault状态栏。 而UIBarStyleBlack将会提供一个UIStatusBarStyleLightContent状态栏。 
TL; DR:
 如果您想在UINavigationController使用UIStatusBarStyleLightContent ,请使用: 
 self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 
所以我实际上添加了一个类别到UINavigationController,但使用的方法:
 -(UIViewController *)childViewControllerForStatusBarStyle; -(UIViewController *)childViewControllerForStatusBarHidden; 
并有那些返回当前可见的UIViewController。 这让当前的可见视图控制器设置自己的首选风格/可见性。
这是一个完整的代码片段:
在Swift中:
 extension UINavigationController { public override func childViewControllerForStatusBarHidden() -> UIViewController? { return self.topViewController } public override func childViewControllerForStatusBarStyle() -> UIViewController? { return self.topViewController } } 
在Objective-C中:
 @interface UINavigationController (StatusBarStyle) @end @implementation UINavigationController (StatusBarStyle) -(UIViewController *)childViewControllerForStatusBarStyle { return self.topViewController; } -(UIViewController *)childViewControllerForStatusBarHidden { return self.topViewController; } @end 
为了好的措施,下面是在UIViewController中实现的方法:
在Swift中
 override public func preferredStatusBarStyle() -> UIStatusBarStyle { return .LightContent } override func prefersStatusBarHidden() -> Bool { return false } 
在Objective-C中
 -(UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; // your own style } - (BOOL)prefersStatusBarHidden { return NO; // your own visibility code } 
最后,请确保您的应用程序plist没有将“基于视图控制器的状态栏外观”设置为NO。 删除该行或将其设置为YES(我相信这是iOS 7的默认设置?)
  泰森的答案是正确的在UINavigationController中将状态栏颜色更改为白色。 
 如果有人希望通过在AppDelegate编写代码来完成相同的结果,那么使用下面的代码并将其写入AppDelegate's didFinishLaunchingWithOptions方法中。 
 不要忘记在.plist文件中将UIViewControllerBasedStatusBarAppearance设置为YES ,否则更改将不会反映出来。 
码
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // status bar appearance code [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]; return YES; } 
对于还在为此而苦恼的人,这个简单的扩展应该可以解决你的问题。
 extension UINavigationController { override open var childViewControllerForStatusBarStyle: UIViewController? { return self.topViewController } } 
除了Hippo的答案:如果您使用的是UINavigationController,那么最好添加一个类别:
 // UINavigationController+StatusBarStyle.h: @interface UINavigationController (StatusBarStyle) @end // UINavigationController+StatusBarStyle.m: @implementation UINavigationController (StatusBarStyle) - (UIStatusBarStyle)preferredStatusBarStyle { //also you may add any fancy condition-based code here return UIStatusBarStyleLightContent; } @end 
该解决scheme可能比切换到即将被弃用的行为更好。
如果你的viewController在UINavigationController下。
子类UINavigationController并添加
 override var preferredStatusBarStyle: UIStatusBarStyle { return topViewController?.preferredStatusBarStyle ?? .default } 
  ViewController的preferredStatusBarStyle将被调用。 
UIStatusBarStyle在iOS 7中
iOS 7中的状态栏是透明的,它后面的视图显示了通过。
 状态栏的风格是指其内容的外观。 在iOS 7中,状态栏内容可能是黑暗的( UIStatusBarStyleDefault )或亮的( UIStatusBarStyleLightContent )。  UIStatusBarStyleBlackTranslucent和UIStatusBarStyleBlackOpaque都在iOS 7.0中被弃用。 改用UIStatusBarStyleLightContent 。 
 如何更改UIStatusBarStyle 
 如果下面的状态栏是一个导航栏,状态栏风格将被调整为与导航栏风格( UINavigationBar.barStyle )相匹配: 
 具体而言,如果导航栏风格是UIBarStyleDefault,则状态栏风格将为UIStatusBarStyleDefault ; 如果导航栏风格是UIBarStyleBlack ,则状态栏风格将是UIStatusBarStyleLightContent 。 
如果状态栏下方没有导航栏,则应用程序运行时,可以通过单独的视图控制器来控制和更改状态栏的样式。
  – [UIViewController preferredStatusBarStyle]是在iOS 7中添加的新方法。可以覆盖返回首选状态栏样式: 
 - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } 
 如果状态栏风格应该由子视图控制器而不是自我控制,则覆盖-[UIViewController childViewControllerForStatusBarStyle]返回该子视图控制器。 
 如果您更愿意select退出此行为,并使用-[UIApplication statusBarStyle]方法设置状态栏样式,请将UIViewControllerBasedStatusBarAppearance关键点添加到应用程序的Info.plist文件中,并将其值设置为NO。 
 上面的答案对于UINavigationControllers来说仍然是一个很好的答案 。 不过,对于swift 3,childViewController函数已经改变为vars 。 所以UINavigationController扩展代码应该是: 
 override open var childViewControllerForStatusBarStyle: UIViewController? { return topViewController } override open var childViewControllerForStatusBarHidden: UIViewController? { return topViewController } 
然后在视图控制器应该指定状态栏的风格:
 override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } 
Swift 3 iOS 10解决scheme:
 override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } 
如果有人正在使用导航控制器,并希望所有的导航控制器都具有黑色风格,那么可以在Swift 3中这样写一个扩展到UINavigationController,它将应用于所有导航控制器(而不是将其分配给一个控制器时间)。
 extension UINavigationController { override open func viewDidLoad() { super.viewDidLoad() self.navigationBar.barStyle = UIBarStyle.black } } 
这是我解决这个问题的方法。
定义一个名为AGViewControllerAppearance的协议。
AGViewControllerAppearance.h
 #import <Foundation/Foundation.h> @protocol AGViewControllerAppearance <NSObject> @optional - (BOOL)showsStatusBar; - (BOOL)animatesStatusBarVisibility; - (UIStatusBarStyle)preferredStatusBarStyle; - (UIStatusBarAnimation)prefferedStatusBarAnimation; @end 
在UIViewController上定义一个名为Upgrade的类别。
的UIViewController + Upgrade.h
 #import <UIKit/UIKit.h> @interface UIViewController (Upgrade) // // Replacements // - (void)upgradedViewWillAppear:(BOOL)animated; @end 
的UIViewController + Upgrade.m
 #import "UIViewController+Upgrade.h" #import <objc/runtime.h> #import "AGViewControllerAppearance.h" // This is the appearance protocol @implementation UIViewController (Upgrade) + (void)load { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wselector" Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:)); #pragma clang diagnostic pop Method upgradedViewWillAppear = class_getInstanceMethod(self, @selector(upgradedViewWillAppear:)); method_exchangeImplementations(viewWillAppear, upgradedViewWillAppear); } #pragma mark - Implementation - (void)upgradedViewWillAppear:(BOOL)animated { // // Call the original message (it may be a little confusing that we're // calling the 'same' method, but we're actually calling the original one :) ) // [self upgradedViewWillAppear:animated]; // // Implementation // if ([self conformsToProtocol:@protocol(AGViewControllerAppearance)]) { UIViewController <AGViewControllerAppearance> *viewControllerConformingToAppearance = (UIViewController <AGViewControllerAppearance> *)self; // // Status bar // if ([viewControllerConformingToAppearance respondsToSelector:@selector(preferredStatusBarStyle)]) { BOOL shouldAnimate = YES; if ([viewControllerConformingToAppearance respondsToSelector:@selector(animatesStatusBarVisibility)]) { shouldAnimate = [viewControllerConformingToAppearance animatesStatusBarVisibility]; } [[UIApplication sharedApplication] setStatusBarStyle:[viewControllerConformingToAppearance preferredStatusBarStyle] animated:shouldAnimate]; } if ([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)]) { UIStatusBarAnimation animation = UIStatusBarAnimationSlide; if ([viewControllerConformingToAppearance respondsToSelector:@selector(prefferedStatusBarAnimation)]) { animation = [viewControllerConformingToAppearance prefferedStatusBarAnimation]; } [[UIApplication sharedApplication] setStatusBarHidden:(! [viewControllerConformingToAppearance showsStatusBar]) withAnimation:animation]; } } } @end 
现在,该说视图控制器正在实现AGViewControllerAppearance协议。
例:
 @interface XYSampleViewController () <AGViewControllerAppearance> ... the rest of the interface @end 
当然,你可以从协议中实现其余的方法( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ), UIViewController + Upgrade将根据它们提供的值进行适当的定制。
如果有人遇到这个问题与UISearchController。 只要创build一个UISearchController的新子类,然后将下面的代码添加到该类中:
 override func preferredStatusBarStyle() -> UIStatusBarStyle { return .LightContent } 
在任何一种UIViewController的Swift中:
 在你的AppDelegate设置: 
 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { window!.rootViewController = myRootController return true } 
  myRootController可以是任何types的UIViewController ,例如UITabBarController或UINavigationController 。 
然后,像这样覆盖这个根控制器:
 class RootController: UIViewController { override func preferredStatusBarStyle() -> UIStatusBarStyle { return .LightContent } } 
这将改变整个应用程序状态栏的外观,因为根控制器是唯一负责状态栏的外观。
 请记住在Info.plist中将View controller-based status bar appearance为YES以使其工作(这是默认设置)。 
 在UINavigationController上, preferredStatusBarStyle不被调用,因为它的topViewController比self更topViewController 。 所以,为了获得在UINavigationController上调用的preferredStatusBarStyle ,你需要改变它的childViewControllerForStatusBarStyle 。 
做一个UINavigationController(我的build议):
 class MyRootNavigationController: UINavigationController { override func preferredStatusBarStyle() -> UIStatusBarStyle { return .LightContent } override func childViewControllerForStatusBarStyle() -> UIViewController? { return nil } } 
为所有UINavigationController(警告:它影响UIDocumentPickerViewController,UIImagePickerController等)做到这一点:
 extension UINavigationController { public override func preferredStatusBarStyle() -> UIStatusBarStyle { return .LightContent } public override func childViewControllerForStatusBarStyle() -> UIViewController? { return nil } } 
NavigationController或TabBarController是需要提供样式的。 这是我解决的方法: https : //stackoverflow.com/a/39072526/242769
 注意当使用self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 解 
一定要去你的plist,并将“查看基于控制器的状态栏外观”设置为YES。 如果它不,它将无法正常工作。