UIStatusBarStyle PreferredStatusBarStyle no funciona en iOS 7

En mi aplicación para iPhone creada con Xcode 5 para iOS 7 configuro UIViewControllerBasedStatusBarAppearance=YES en info.plist , y en mi ViewController tengo este código:

 -(UIStatusBarStyle) preferredStatusBarStyle { return UIStatusBarStyleLightContent; } 

Pero la barra de estado sigue siendo negra contra el fondo negro.

Sé que es posible cambiar esta aplicación UIViewControllerBasedStatusBarAppearance=NO en info.plist , pero realmente necesito modificar esto en un viewController de viewController por viewController en tiempo de ejecución.

Descubrí que si su ViewController está dentro de un navigationController, el navigationBar.barStyle de navigationBar.barStyle determina el statusBarStyle.

Configurando su barStyle de UIBarStyleBlackTranslucent dará texto de barra de estado blanco (es decir, UIStatusBarStyleLightContent ), y UIBarStyleDefault dará texto de barra de estado negro (es decir, UIStatusBarStyleDefault ).

Tenga en cuenta que esto se aplica incluso si cambia totalmente el color de la barTintColor navegación a través de su barTintColor .

OK, aquí está el truco. Debe agregar la clave “Ver barra de estado basada en el controlador” y establecer el valor en No.

Esto es contrario a lo que parece el significado de esta clave, pero incluso si establece el valor en No , aún puede cambiar la apariencia de la barra de estado, y si se muestra o no en cualquier controlador de vista. ¡Así que actúa como “Sí” pero lo establece en “No”!

Ahora puedo obtener la barra de estado en blanco u oscuro.

Para preferredStatusBarStyle() para trabajar dentro de UINavigationController y UITabBarController agrego el siguiente código, que obtendrá el estilo de barra de estado preferido del controlador de vista actualmente visible.

 extension UITabBarController { public override func childViewControllerForStatusBarStyle() -> UIViewController? { return selectedViewController } } extension UINavigationController { public override func childViewControllerForStatusBarStyle() -> UIViewController? { return visibleViewController } } 

Para Swift 3, esos no son métodos, sino propiedades:

 extension UITabBarController { open override var childViewControllerForStatusBarStyle: UIViewController? { return selectedViewController } } extension UINavigationController { open override var childViewControllerForStatusBarStyle: UIViewController? { return visibleViewController } } 

Uso

 class ViewController: UIViewController { // This will be called every time the ViewController appears // Works great for pushing & popping override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } } 

Puede que llegue a esto un poco tarde, pero en el caso de que alguien más esté buscando una solución de aplicación que funcione y sea verificada.

@mxcl está en lo correcto al describir por qué sucede esto. Para corregirlo, simplemente creamos una extensión (o categoría en obj-c) que anula el métodoSatusBarStyle () preferido de UINavigationController. Aquí hay un ejemplo en Swift:

 extension UINavigationController { public override func preferredStatusBarStyle() -> UIStatusBarStyle { if let rootViewController = self.viewControllers.first { return rootViewController.preferredStatusBarStyle() } return super.preferredStatusBarStyle() } } 

Este código simplemente extrae el primer controlador de vista (el controlador de vista raíz) y lo desenvuelve (en obj-c simplemente verifique que no sea nulo). Si el desenvolvimiento es exitoso (no nulo), entonces tomamos rootViewControllers preferredStatusBarStyle. De lo contrario, solo devolvemos el valor predeterminado.

Espero que esto ayude a cualquiera que pueda necesitarlo.

Para proporcionar más detalles sobre la respuesta aceptada, coloque la siguiente línea en el método didFinishLaunchingWithOptions: su delegado de didFinishLaunchingWithOptions: :

 [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; 

Luego, en su Info.plist, agregue View controller-based status bar appearance configúrelo en NO .

Creo que así es como debería hacerse, NO desde el controlador de navegación, si quiere el mismo color de barra de estado para toda la aplicación. Es posible que tenga pantallas que no estén necesariamente integradas en un UINavigationController , o una subclase UINavigationController diferente en otro lugar, y otras cosas.

EDITAR : También puede hacerlo sin escribir ningún código: https://stackoverflow.com/a/18732865/855680

En viewDidLoad solo escribe esto

 [self setNeedsStatusBarAppearanceUpdate]; 

solo haz eso y funcionará

puedes por favor prueba esto

 Set UIViewControllerBasedStatusBarAppearance to NO. Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 

Una cosa más que he visto en su pregunta es que usted ha escrito el método de esta manera

  -(void)UIStatusBarStyle PreferredStatusBarStyle () { return UIStatusBarStyle.LightContent; } 

pero debería ser así

 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } 

Así es como lo resolví. Usualmente el navigationController o tabBarController son los que deciden la apariencia de la barra de estado (oculta, color, etc.).

Así que terminé subclasando el controlador de navegación y anulando preferredStatusBarStyle. si ViewContorller visible actual implementa StatusBarStyleHandler, solicito el valor que se utilizará como estilo, si no lo hago, simplemente devuelvo un valor predeterminado.

La forma en que desencadena una actualización de la apariencia de la barra de estado es llamando a setNeedsStatusBarAppearanceUpdate que desencadena preferredStatusBarStyle nuevamente y actualiza la IU según lo que devuelve el método.

 public protocol StatusBarStyleHandler { var preferredStatusBarStyle: UIStatusBarStyle { get } } public class CustomNavigationCotnroller: UINavigationController { public override var preferredStatusBarStyle: UIStatusBarStyle { if let statusBarHandler = visibleViewController as? StatusBarStyleHandler { return statusBarHandler.preferredStatusBarStyle } return .default } } 

Entonces uso

 public class SomeController: UIViewController, StatusBarStyleHandler { private var statusBarToggle = true // just a sample for toggling the status bar style each time method is called private func toggleStatusBarColor() { statusBarToggle = !statusBarToggle setNeedsStatusBarAppearanceUpdate() } public override var preferredStatusBarStyle: UIStatusBarStyle { return statusBarToggle ? .lightContent : .default } } 

Incluso con todas las respuestas aquí todavía no encontré la solución exacta para mí, pero comencé con la respuesta de Daniel. Con lo que terminé fue:

 override var preferredStatusBarStyle: UIStatusBarStyle { return visibleViewController?.preferredStatusBarStyle ?? .lightContent } 

en los controladores de navegación (similar para la pestaña, simplemente selectedViewController). Y luego respetará lo siguiente:

 override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } 

En cada controlador de vista a menos que lo configure de otra manera. No necesito llamar a setNeedsStatusBarAppearanceUpdate() ninguna parte, solo se actualiza cuando llegue a cada controlador de vista.

1) Una configuración para todo el proyecto:

Si está disponible, elimine el UIViewControllerBasedStatusBarAppearance clave-valor UIViewControllerBasedStatusBarAppearance de su info.plist o establezca NO sin eliminarlo. Si no está disponible en su info.plist, no haga nada. El valor predeterminado es NO para esta propiedad.

Agregue el código siguiente a su AppDelegate.m:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; } 

2) diferentes configuraciones para diferentes controladores de vista:

Agregue el UIViewControllerBasedStatusBarAppearance clave-valor UIViewControllerBasedStatusBarAppearance a su info.plist y ajústelo a YES .

Si su controlador de vista no está incrustado en el controlador de navegación. Digamos MyViewController. solo agrega el código a continuación a tu archivo MyViewController.m. Si su Controlador de Vista está incrustado en el Controlador de navegación, cree una nueva Clase Cocoa Touch y conviértalo en la subclase de UINavigationController. Digamos MyNC. Seleccione Vista de controlador de navegación en su Guión gráfico, en el panel derecho; Utilidades -> Identity Inspector -> Custom Class -> Class, escriba “MyNC”. Después de vincular Storyboard View con su clase Cocoa Touch “MyNC”, agregue el siguiente código a su MyNC.m:

 - (BOOL)prefersStatusBarHidden { return NO; } -(UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } 

Si en caso de que quisieras ocultar el statusBar durante splashScreen pero quisieras cambiar el estilo a contenido ligero (StatusBarInitiallyHidden en Plist tiene que ser NO para ocultar statusBar en splash), puedes agregar esto al método appDelegate didFinishLaunchingWithOptions para cambiar a lightContent.

 [[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent]; 

rápido ejemplo

en AppDelegate.swift

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent; return true } 

en info.plist set Ver apariencia de barra de estado basada en controlador: NO

Si está utilizando NavigationController , puede subclasificar NavigationController para que consulte su controlador de vista secundaria

// MyCustomNavigationController

 - (NSUInteger)supportedInterfaceOrientations { UIViewController *viewControllerToAsk = [self findChildVC]; return [viewControllerToAsk supportedInterfaceOrientations]; } - (BOOL)shouldAutorotate { UIViewController *viewControllerToAsk = [self findChildVC]; return [viewControllerToAsk shouldAutorotate]; } - (UIStatusBarStyle)preferredStatusBarStyle { UIViewController *viewControllerToAsk = [self findChildVC]; return [viewControllerToAsk preferredStatusBarStyle]; } - (UIViewController *)findChildVC { return self.viewControllers.firstObject; } 

Puede establecer el estilo de la barra de estado. Se parecerá a la barra de estado como IOS 6 y siguientes.
Pegue estos métodos en su controlador de vista

 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleBlackOpaque; } 

y llamar a este método desde la vista se cargó así

 if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) { [self setNeedsStatusBarAppearanceUpdate]; } 

Para swift 3, en su UIViewController:

 override var preferredStatusBarStyle : UIStatusBarStyle { return UIStatusBarStyle.lightContent } 

Swift 4.2

 extension UITabBarController { open override var childForStatusBarStyle: UIViewController? { return selectedViewController } } extension UINavigationController { open override var childForStatusBarStyle: UIViewController? { return visibleViewController } }