prefernetworkingStatusBarStyle no se llama

Seguí este hilo para anular -prefernetworkingStatusBarStyle , pero no se llama. ¿Hay alguna opción que pueda cambiar para habilitarla? (Estoy usando XIB en mi proyecto).

Posible causa raíz

Tuve el mismo problema y descubrí que estaba sucediendo porque no estaba configurando el controller de vista raíz en la window de mi aplicación.

El UIViewController en el que implementé el prefernetworkingStatusBarStyle se usó en un UITabBarController , que controlaba la apariencia de las vistas en la pantalla.

Cuando establecí el controller de vista raíz para señalar a este UITabBarController , los cambios en la barra de estado comenzaron a funcionar correctamente, como se esperaba (y se UITabBarController el método prefernetworkingStatusBarStyle ).

 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // other view controller loading/setup code self.window.rootViewController = rootTabBarController; [self.window makeKeyAndVisible]; return YES; } 

Método alternativo (Desaprobado en iOS 9)

De forma alternativa, puede llamar a uno de los siguientes methods, según corresponda, en cada uno de sus controlleres de vista, en function de su color de background, en lugar de tener que usar setNeedsStatusBarAppearanceUpdate :

 [[UIApplication shanetworkingApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 

o

 [[UIApplication shanetworkingApplication] setStatusBarStyle:UIStatusBarStyleDefault]; 

Tenga en count que también deberá configurar UIViewControllerBasedStatusBarAppearance en el file NO en el file Plist si usa este método.

Para cualquier persona que use un UINavigationController:

UINavigationController no reenvía prefernetworkingStatusBarStyle llamadas prefernetworkingStatusBarStyle a sus controlleres secundarios de vista. En cambio, administra su propio estado, como debería ser, dibuja en la parte superior de la pantalla donde vive la barra de estado y, por lo tanto, debe ser responsable de ella. Por lo tanto, la implementación de prefernetworkingStatusBarStyle en sus VC dentro de un controller de navigation no hará nada, nunca serán invocados.

El truco es qué usa UINavigationController para decidir qué devolver para UIStatusBarStyleDefault o UIStatusBarStyleLightContent . Basa esto en su UINavigationBar.barStyle . El valor pnetworkingeterminado ( UIBarStyleDefault ) da como resultado la barra de estado oscura de primer plano UIStatusBarStyleDefault . Y UIBarStyleBlack dará una UIStatusBarStyleLightContent estado UIStatusBarStyleLightContent .

TL, DR:

Si desea que UIStatusBarStyleLightContent en un UINavigationController use:

 self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 

Entonces, realmente agregué una categoría a UINavigationController pero utilicé los methods:

 -(UIViewController *)childViewControllerForStatusBarStyle; -(UIViewController *)childViewControllerForStatusBarHidden; 

y si esos devuelven el UIViewController visible actual. Eso permite que el controller de vista visible actual establezca su propio estilo / visibilidad preferido.

Aquí hay un fragment de código completo para ello:

En Swift:

 extension UINavigationController { public override func childViewControllerForStatusBarHidden() -> UIViewController? { return self.topViewController } public override func childViewControllerForStatusBarStyle() -> UIViewController? { return self.topViewController } } 

En Objective-C:

 @interface UINavigationController (StatusBarStyle) @end @implementation UINavigationController (StatusBarStyle) -(UIViewController *)childViewControllerForStatusBarStyle { return self.topViewController; } -(UIViewController *)childViewControllerForStatusBarHidden { return self.topViewController; } @end 

Y, en buena medida, así es como se implementa en un UIViewController:

En swift

 override public func prefernetworkingStatusBarStyle() -> UIStatusBarStyle { return .LightContent } override func prefersStatusBarHidden() -> Bool { return false } 

En Objective-C

 -(UIStatusBarStyle)prefernetworkingStatusBarStyle { return UIStatusBarStyleLightContent; // your own style } - (BOOL)prefersStatusBarHidden { return NO; // your own visibility code } 

Finalmente, asegúrese de que su aplicación no tenga la "apariencia de la barra de estado basada en el controller de la vista" establecida en NO. Elimine esa línea o configúrela en SÍ (¿cuál es el valor pnetworkingeterminado ahora para iOS 7?)

La respuesta de Tyson es correcta para cambiar el color de la barra de estado a blanco en UINavigationController .

Si alguien quiere lograr el mismo resultado escribiendo el código en AppDelegate , utilice el código siguiente y escríbalo dentro AppDelegate's método didFinishLaunchingWithOptions AppDelegate's .

Y no olvide configurar UIViewControllerBasedStatusBarAppearance en YES en el file .plist, de lo contrario, el cambio no se reflejará.

Código

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // status bar appearance code [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]; return YES; } 

Para cualquiera que todavía esté luchando con esto, esta simple extensión rápida debe solucionar el problema por usted.

 extension UINavigationController { override open var childViewControllerForStatusBarStyle: UIViewController? { return self.topViewController } } 

Una adición a la respuesta de Hippo: si está usando un UINavigationController, es probable que sea mejor agregar una categoría:

 // UINavigationController+StatusBarStyle.h: @interface UINavigationController (StatusBarStyle) @end // UINavigationController+StatusBarStyle.m: @implementation UINavigationController (StatusBarStyle) - (UIStatusBarStyle)prefernetworkingStatusBarStyle { //also you may add any fancy condition-based code here return UIStatusBarStyleLightContent; } @end 

Probablemente, esa solución sea mejor que cambiar a un comportamiento que ya no está en desuso.

UIStatusBarStyle en iOS 7

La barra de estado en iOS 7 es transparente, se ve la vista detrás de ella.

El estilo de la barra de estado se refiere a las apariencias de su contenido. En iOS 7, el contenido de la barra de estado es oscuro ( UIStatusBarStyleDefault ) o ligero ( UIStatusBarStyleLightContent ). Tanto UIStatusBarStyleBlackTranslucent como UIStatusBarStyleBlackOpaque están en desuso en iOS 7.0. Use UIStatusBarStyleLightContent en UIStatusBarStyleLightContent lugar.

Cómo cambiar UIStatusBarStyle

Si debajo de la barra de estado hay una barra de navigation, el estilo de la barra de estado se ajustará para que coincida con el estilo de la barra de navigation ( UINavigationBar.barStyle ):

Específicamente, si el estilo de la barra de navigation es UIBarStyleDefault, el estilo de la barra de estado será UIStatusBarStyleDefault ; si el estilo de la barra de navigation es UIBarStyleBlack , el estilo de la barra de estado será UIStatusBarStyleLightContent .

Si no hay una barra de navigation debajo de la barra de estado, el estilo de la barra de estado puede ser controlado y modificado por un controller de vista individual mientras se ejecuta la aplicación.

[UIViewController prefernetworkingStatusBarStyle] es un nuevo método añadido en iOS 7. Se puede replace para devolver el estilo de barra de estado preferido:

 - (UIStatusBarStyle)prefernetworkingStatusBarStyle { return UIStatusBarStyleLightContent; } 

Si el estilo de la barra de estado debe ser controlado por un controller de vista secundario en lugar de uno mismo, anule -[UIViewController childViewControllerForStatusBarStyle] para devolver ese controller de vista secundaria.

Si prefiere inhabilitar este comportamiento y establecer el estilo de barra de estado utilizando el método -[UIApplication statusBarStyle] , agregue la key Info.plist file Info.plist una aplicación y Info.plist el valor NO.

La respuesta de @serenn anterior es aún excelente para el caso de UINavigationControllers. Sin embargo, para swift 3 las funciones childViewController se han cambiado a vars . Por lo tanto, el código de extensión UINavigationController debe ser:

 override open var childViewControllerForStatusBarStyle: UIViewController? { return topViewController } override open var childViewControllerForStatusBarHidden: UIViewController? { return topViewController } 

Y luego, en el controller de vista, debería dictar el estilo de barra de estado:

 override var prefernetworkingStatusBarStyle: UIStatusBarStyle { return .lightContent } 

Si su viewController está bajo UINavigationController.

Subclass UINavigationController y agregue

 override var prefernetworkingStatusBarStyle: UIStatusBarStyle { return topViewController?.prefernetworkingStatusBarStyle ?? .default } 

Se invitará a PrefernetworkingStatusBarStyle de ViewController.

Solución Swift 3 iOS 10:

 override var prefernetworkingStatusBarStyle: UIStatusBarStyle { return .lightContent } 

Si alguien está utilizando un controller de navigation y quiere que todos sus controlleres de navigation tengan el estilo negro, puede escribir una extensión a UINavigationController como esta en Swift 3 y se aplicará a todos los controlleres de navigation (en lugar de asignarlo a un controller en un hora).

 extension UINavigationController { override open func viewDidLoad() { super.viewDidLoad() self.navigationBar.barStyle = UIBarStyle.black } } 

Aquí está mi método para resolver esto.

Defina un protocolo llamado AGViewControllerAppearance .

AGViewControllerAppearance.h

 #import <Foundation/Foundation.h> @protocol AGViewControllerAppearance <NSObject> @optional - (BOOL)showsStatusBar; - (BOOL)animatesStatusBarVisibility; - (UIStatusBarStyle)prefernetworkingStatusBarStyle; - (UIStatusBarAnimation)preffenetworkingStatusBarAnimation; @end 

Defina una categoría en UIViewController llamada 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 ignonetworking "-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(prefernetworkingStatusBarStyle)]) { BOOL shouldAnimate = YES; if ([viewControllerConformingToAppearance respondsToSelector:@selector(animatesStatusBarVisibility)]) { shouldAnimate = [viewControllerConformingToAppearance animatesStatusBarVisibility]; } [[UIApplication shanetworkingApplication] setStatusBarStyle:[viewControllerConformingToAppearance prefernetworkingStatusBarStyle] animated:shouldAnimate]; } if ([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)]) { UIStatusBarAnimation animation = UIStatusBarAnimationSlide; if ([viewControllerConformingToAppearance respondsToSelector:@selector(preffenetworkingStatusBarAnimation)]) { animation = [viewControllerConformingToAppearance preffenetworkingStatusBarAnimation]; } [[UIApplication shanetworkingApplication] setStatusBarHidden:(! [viewControllerConformingToAppearance showsStatusBar]) withAnimation:animation]; } } } @end 

Ahora, es hora de decir que usted ve el controller implementando el protocolo AGViewControllerAppearance .

Ejemplo:

 @interface XYSampleViewController () <AGViewControllerAppearance> ... the rest of the interface @end 

Por supuesto, puede implementar el rest de los methods ( showsStatusBar , animatesStatusBarVisibility , preffenetworkingStatusBarAnimation ) del protocolo y UIViewController + Upgrade realizará la personalización adecuada en function de los valores proporcionados por ellos.

Si alguien se encuentra con este problema con UISearchController. Simplemente cree una nueva subclass de UISearchController y luego agregue el código a continuación en esa class:

 override func prefernetworkingStatusBarStyle() -> UIStatusBarStyle { return .LightContent } 

En Swift para cualquier tipo de UIViewController:

En su set de AppDelegate :

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { window!.rootViewController = myRootController return true } 

myRootController puede ser cualquier tipo de UIViewController , por ejemplo UITabBarController o UINavigationController .

Luego, anule este controller raíz de esta manera:

 class RootController: UIViewController { override func prefernetworkingStatusBarStyle() -> UIStatusBarStyle { return .LightContent } } 

Esto cambiará la apariencia de la barra de estado en toda la aplicación, ya que el controller raíz es el único responsable de la apariencia de la barra de estado.

Recuerde establecer la propiedad View controller-based status bar appearance en el Info.plist en YES en su Info.plist para que esto funcione (que es el valor pnetworkingeterminado).

En un UINavigationController, prefernetworkingStatusBarStyle no se llama porque su topViewController se prefiere a self . Por lo tanto, para get calledStatusBarStyle prefernetworkingStatusBarStyle en un UINavigationController, debe cambiar su childViewControllerForStatusBarStyle .

Para hacerlo por un UINavigationController (mi recomendación):

 class MyRootNavigationController: UINavigationController { override func prefernetworkingStatusBarStyle() -> UIStatusBarStyle { return .LightContent } override func childViewControllerForStatusBarStyle() -> UIViewController? { return nil } } 

Para hacerlo para todo UINavigationController (advertencia: afecta a UIDocumentPickerViewController, UIImagePickerController, etc.):

 extension UINavigationController { public override func prefernetworkingStatusBarStyle() -> UIStatusBarStyle { return .LightContent } public override func childViewControllerForStatusBarStyle() -> UIViewController? { return nil } } 

El NavigationController o TabBarController son los que necesitan proporcionar el estilo. Así es como solucioné: https://stackoverflow.com/a/39072526/242769

Tenga en count que al usar el self.navigationController.navigationBar.barStyle = UIBarStyleBlack; solución

asegúrese de ir a su plist y configurar "Ver la apariencia de la barra de estado basada en el controller" en SÍ. Si es NO, no funcionará.