Seguí este hilo para anular -preferredStatusBarStyle
, pero no se llama. ¿Hay alguna opción que pueda cambiar para habilitarla? (Estoy usando XIB en mi proyecto).
ios
ios7
uikit
uistatusbar
trgoofi
fuente
fuente
Respuestas:
Posible causa raíz
Tuve el mismo problema y descubrí que estaba sucediendo porque no estaba configurando el controlador de vista raíz en la ventana de mi aplicación.
El
UIViewController
en el que había implementadopreferredStatusBarStyle
fue utilizado en unUITabBarController
, que controlaba la apariencia de las vistas en la pantalla.Cuando configuré el controlador de vista raíz para que apunte a esto
UITabBarController
, los cambios en la barra de estado comenzaron a funcionar correctamente, como se esperaba (ypreferredStatusBarStyle
se estaba llamando al método).Método alternativo (en desuso en iOS 9)
Alternativamente, puede llamar a uno de los siguientes métodos, según corresponda, en cada uno de sus controladores de vista, dependiendo de su color de fondo, en lugar de tener que usar
setNeedsStatusBarAppearanceUpdate
:o
Tenga en cuenta que también tendrá que establecer
UIViewControllerBasedStatusBarAppearance
queNO
en el archivo plist si se utiliza este método.fuente
setNeedsStatusBarAppearanceUpdate
; mis sospechas se confirmaron cuando hice este cambio.Para cualquiera que use un UINavigationController:
El
UINavigationController
no reenvía laspreferredStatusBarStyle
llamadas a sus controladores de vista secundarios. En cambio, administra su propio estado, como debería, está dibujando en la parte superior de la pantalla donde vive la barra de estado y, por lo tanto, debería ser responsable de ello. Por lo tanto, la implementaciónpreferredStatusBarStyle
en sus VC dentro de un controlador de navegación no hará nada, nunca se los llamará.El truco es lo que la
UINavigationController
utiliza para decidir qué volver aUIStatusBarStyleDefault
oUIStatusBarStyleLightContent
. Basa esto en suUINavigationBar.barStyle
. El valor predeterminado (UIBarStyleDefault
) da como resultado laUIStatusBarStyleDefault
barra de estado de primer plano oscuro . YUIBarStyleBlack
le dará unaUIStatusBarStyleLightContent
barra de estado.TL; DR:
Si quieres
UIStatusBarStyleLightContent
unUINavigationController
uso:fuente
preferredStatusBarStyle
en cuenta que , de hecho, se llamará al controlador de vista secundario si oculta la barra de navegación (establecidanavigationBarHidden
enYES
), exactamente según corresponda.[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
conjunto aYES
realmente habrápreferredStatusBarStyle
llamado, y una advertencia a aquellos que podrían tropezar con esto: ¡funciona connavigationBarHidden
, pero no connavigationBar.hidden
!Así que en realidad agregué una categoría a UINavigationController pero usé los métodos:
y los devolvió el UIViewController visible actual. Eso permite que el controlador de vista visible actual establezca su propio estilo / visibilidad preferida.
Aquí hay un fragmento de código completo para ello:
En Swift:
En el objetivo-C:
Y por si acaso, así es como se implementa en un UIViewController:
En veloz
En el objetivo-C
Finalmente, asegúrese de que su lista de aplicaciones NO tenga la opción "Ver la apariencia de la barra de estado basada en el controlador" en NO. ¿Eliminar esa línea o establecerla en SÍ (que creo que es el predeterminado ahora para iOS 7?)
fuente
return self.topViewController;
funciona para mí, peroreturn self.visibleViewController;
, nosuper
a este método y realmente desea cambiar el comportamiento de todos los controladores de este tipoPara cualquiera que todavía tenga dificultades con esto, esta simple extensión en Swift debería solucionar el problema por usted.
fuente
Mi aplicación utiliza los tres:
UINavigationController
,UISplitViewController
,UITabBarController
, por tanto, todos éstos parecen tomar el control de la barra de estado y causaránpreferedStatusBarStyle
a no ser llamado por sus hijos. Para anular este comportamiento, puede crear una extensión como el resto de las respuestas han mencionado. Aquí hay una extensión para los tres, en Swift 4. Desearía que Apple fuera más claro sobre este tipo de cosas.Editar: Actualización para cambios en la API de Swift 4.2
fuente
La respuesta de Tyson es correcta para cambiar el color de la barra de estado a blanco
UINavigationController
.Si alguien quiere lograr el mismo resultado escribiendo el código
AppDelegate
, use el siguiente código y escríbalo dentro delAppDelegate's
didFinishLaunchingWithOptions
método.Y no se olvide de establecer el
UIViewControllerBasedStatusBarAppearance
queYES
en el archivo plist, de lo contrario el cambio no se reflejará.Código
fuente
En un UINavigationController,
preferredStatusBarStyle
no se llama porquetopViewController
se prefiereself
. Entonces, para que tepreferredStatusBarStyle
llamen en un UINavigationController, debes cambiarlochildViewControllerForStatusBarStyle
.Recomendación
Anule su UINavigationController en su clase:
Alternativa no recomendada
Para hacerlo para todos los UINavigationController, puede anular una extensión (advertencia: afecta a UIDocumentPickerViewController, UIImagePickerController, etc.), pero probablemente no debería hacerlo de acuerdo con la documentación de Swift :
fuente
Además de la respuesta de serenn, si presenta un controlador de vista con un
modalPresentationStyle
(por ejemplo.overCurrentContext
), también debe llamar a esto en el controlador de vista recién presentado:No olvide anular también el
preferredStatusBarStyle
controlador de vista presentado.fuente
Una adición a la respuesta de Hippo: si está utilizando un UINavigationController, entonces probablemente sea mejor agregar una categoría:
Esa solución es probablemente mejor que cambiar a un comportamiento que pronto será obsoleto.
fuente
preferredStatusBarStyle
y hace la lógica específica del UINavigationController. En este momento, esta lógica se basa,navigationBar.barStyle
pero puedo ver que se agregan verificaciones adicionales (por ejemplo,UISearchDisplayController
mover para ocultar el modo de barra de navegación). Al anular la lógica predeterminada, pierde toda esta funcionalidad y se deja abierto para los molestos momentos 'wtf' en el futuro. Consulte mi respuesta anterior para ver la forma correcta de hacer esto mientras aún admite el comportamiento del controlador de navegación incorporado.Swift 4.2 y superior
Como se menciona en la respuesta seleccionada , la causa raíz es verificar el objeto del controlador de vista raíz de la ventana.
Posibles casos de su estructura de flujo
es un controlador de vista de raíz de ventana.
Este tipo de flujo generalmente se usa si su aplicación tiene un flujo de inicio de sesión previo en la pila de navegación sin pestañas y un flujo de inicio de sesión posterior con pestañas y posiblemente cada pestaña contenga aún más el controlador de navegación.
Este es el flujo en el que el controlador de vista raíz de la ventana es tabBarController, posiblemente todas las pestañas tienen más control de navegación.
Este es el flujo donde el controlador de vista raíz de ventana es navigationController.
No estoy seguro de si existe la posibilidad de agregar un controlador de barra de pestañas o un nuevo controlador de navegación en un controlador de navegación existente. Pero si es así, debemos pasar el control de estilo de la barra de estado al siguiente contenedor. Entonces, agregué la misma verificación en la extensión UINavigationController para encontrar
childForStatusBarStyle
Use las siguientes extensiones, maneja todos los escenarios anteriores :
UIViewControllerBasedStatusBarAppearance
claveinfo.plist
ya que es verdadera por defectoPuntos a considerar para flujos más complejos
En caso de que presente un nuevo flujo modalmente, se separa del flujo de estilo de la barra de estado existente. Por lo tanto, suponga que está presentando un
NewFlowUIViewController
y luego agrega un nuevo controlador de navegación o tabBar aNewFlowUIViewController
, luego agrega una extensiónNewFlowUIViewController
también para administrar el estilo de la barra de estado del controlador de vista adicional.En caso de que establezca modalPresentationStyle que no sea
fullScreen
mientras se presenta modalmente, debe establecerlomodalPresentationCapturesStatusBarAppearance
en verdadero para que el controlador de vista presentado deba recibir el control de apariencia de la barra de estado.fuente
Soluciones iOS 13
UINavigationController
es una subclase deUIViewController
(quién sabía 🙃)!Por lo tanto, al presentar controladores de vista integrados en los controladores de navegación, en realidad no está presentando los controladores de vista integrados; ¡Estás presentando los controladores de navegación!
UINavigationController
, como una subclase deUIViewController
, heredapreferredStatusBarStyle
ychildForStatusBarStyle
, que puede establecer como desee.Cualquiera de los siguientes métodos debería funcionar:
info.plist
, agregue la siguiente propiedad:UIUserInterfaceStyle
(también conocido como "Estilo de interfaz de usuario")Anular
preferredStatusBarStyle
dentroUINavigationController
preferredStatusBarStyle
( doc ): el estilo de barra de estado preferido para el controlador de vistaSubclase o extensión
UINavigationController
O
Anular
childForStatusBarStyle
dentroUINavigationController
childForStatusBarStyle
( doc ): se llama cuando el sistema necesita el controlador de vista para determinar el estilo de la barra de estadoSubclase o extensión
UINavigationController
O
Puede devolver cualquier controlador de vista que desee arriba. Recomiendo uno de los siguientes:
topViewController
(ofUINavigationController
) ( doc ): el controlador de vista en la parte superior de la pila de navegaciónvisibleViewController
(ofUINavigationController
) ( doc ): el controlador de vista asociado con la vista actualmente visible en la interfaz de navegación (sugerencia: esto puede incluir "un controlador de vista que se presentó modalmente en la parte superior del controlador de navegación")Nota: Si decide subclase
UINavigationController
, recuerde aplicar esa clase a sus controladores de navegación a través del inspector de identidad en IB.PD Mi código usa la sintaxis Swift 5.1 😎
fuente
La respuesta de @ serenn anterior sigue siendo excelente para el caso de UINavigationControllers. Sin embargo, para swift 3, las funciones childViewController se han cambiado a
vars
. Entonces elUINavigationController
código de extensión debe ser:Y luego en el controlador de vista que debería dictar el estilo de la barra de estado:
fuente
Si su viewController está bajo UINavigationController.
Subclase UINavigationController y agregar
preferredStatusBarStyle
Se llamará a ViewController .fuente
UIStatusBarStyle en iOS 7
La barra de estado en iOS 7 es transparente, la vista detrás se muestra.
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 claro (UIStatusBarStyleLightContent
). AmbosUIStatusBarStyleBlackTranslucent
yUIStatusBarStyleBlackOpaque
están en desuso en iOS 7.0. UtilizarUIStatusBarStyleLightContent
lugar.Como cambiar
UIStatusBarStyle
Si debajo de la barra de estado hay una barra de navegación, el estilo de la barra de estado se ajustará para que coincida con el estilo de la barra de navegación (
UINavigationBar.barStyle
):Específicamente, si el estilo de la barra de navegación es UIBarStyleDefault, el estilo de la barra de estado será
UIStatusBarStyleDefault
; si el estilo de la barra de navegación esUIBarStyleBlack
, el estilo de la barra de estado seráUIStatusBarStyleLightContent
.Si no hay una barra de navegación debajo de la barra de estado, el estilo de la barra de estado puede ser controlado y cambiado por un controlador de vista individual mientras se ejecuta la aplicación.
-
[UIViewController preferredStatusBarStyle]
es un nuevo método agregado en iOS 7. Se puede anular para devolver el estilo de barra de estado preferido:Si el estilo de la barra de estado debe ser controlado por un controlador de vista secundario en lugar de uno mismo, anule
-[UIViewController childViewControllerForStatusBarStyle]
para devolver ese controlador de vista secundario.Si prefiere optar por este comportamiento y establecer el estilo de la barra de estado mediante el
-[UIApplication statusBarStyle]
método, agregue laUIViewControllerBasedStatusBarAppearance
clave alInfo.plist
archivo de una aplicación y dele el valor NO.fuente
Si alguien está usando un controlador de navegación y quiere que todos sus controladores de navegación tengan el estilo negro, puede escribir una extensión para UINavigationController como esta en Swift 3 y se aplicará a todos los controladores de navegación (en lugar de asignarlo a un controlador en un hora).
fuente
En Swift para cualquier tipo de UIViewController:
En tu
AppDelegate
conjunto:myRootController
puede ser cualquier tipo deUIViewController
, por ejemplo,UITabBarController
oUINavigationController
.Luego, anule este controlador raíz de esta manera:
Esto cambiará la apariencia de la barra de estado en toda su aplicación, porque el controlador 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 SÍ en suInfo.plist
para hacer que esto funcione (que es el valor predeterminado).fuente
Solución Swift 3 para iOS 10:
fuente
La mayoría de las respuestas no incluyen una buena implementación del
childViewControllerForStatusBarStyle
método paraUINavigationController
. Según mi experiencia, debe manejar casos como cuando se presenta un controlador de vista transparente sobre un controlador de navegación. En estos casos, debe pasar el control a su controlador modal (visibleViewController
), pero no cuando está desapareciendo.fuente
En mi caso, he presentado accidentalmente el controlador de vista / navegación como
UIModalPresentationStyle.overFullScreen
, lo que hace quepreferredStatusBarStyle
no se llame. Después de volver a cambiarloUIModalPresentationStyle.fullScreen
, todo funciona.fuente
En cuanto a iOS 13.4 , no se llamará al
preferredStatusBarStyle
método en laUINavigationController
categoría, swizzling parece ser la única opción sin la necesidad de usar una subclase.Ejemplo:
Encabezado de categoría:
Implementación:
Uso en AppDelegate.h:
fuente
Aquí está mi método para resolver esto.
Defina un protocolo llamado AGViewControllerAppearance .
AGViewControllerAppearance.h
Defina una categoría en UIViewController llamada Upgrade .
UIViewController + Upgrade.h
UIViewController + Upgrade.m
Ahora, es hora de decir que su controlador de vista está implementando el AGViewControllerAppearance protocolo .
Ejemplo:
Por supuesto, se puede implementar el resto de los métodos ( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) del protocolo y UIViewController + Upgrade va a hacer la personalización adecuada en función de los valores proporcionados por ellos.
fuente
Si alguien se encuentra con este problema con UISearchController. Simplemente cree una nueva subclase de UISearchController y luego agregue el código a continuación en esa clase:
fuente
Tenga en cuenta que al usar el
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
soluciónasegúrese de ir a su lista y establezca "Ver apariencia de la barra de estado basada en el controlador" en SÍ. Si es NO, no funcionará.
fuente
Desde Xcode 11.4, anulando el
preferredStatusBarStyle
propiedad en una extensión UINavigationController ya no funciona ya que no se llamará.Establecer el valor
barStyle
denavigationBar
to.black
funciona, pero esto agregará efectos secundarios no deseados si agrega subvistas a la barra de navegación que pueden tener diferentes apariencias para el modo claro y oscuro. Porque al configurarlobarStyle
en negro, eluserInterfaceStyle
de una vista que está incrustada en la barra de navegación siempre tendráuserInterfaceStyle.dark
independientementeuserInterfaceStyle
de la aplicación.La solución adecuada que se me ocurre es agregar una subclase de
UINavigationController
y anularpreferredStatusBarStyle
allí. Si luego utiliza este UINavigationController personalizado para todas sus vistas, estará en el lado de guardar.fuente
NavigationController o TabBarController son los que necesitan proporcionar el estilo. Así es como lo resolví: https://stackoverflow.com/a/39072526/242769
fuente