Ho seguito questo thread per sovrascrivere -preferredStatusBarStyle
, ma non viene chiamato. Ci sono opzioni che posso modificare per abilitarlo? (Sto usando XIB nel mio progetto.)
Ho seguito questo thread per sovrascrivere -preferredStatusBarStyle
, ma non viene chiamato. Ci sono opzioni che posso modificare per abilitarlo? (Sto usando XIB nel mio progetto.)
Risposte:
Ho avuto lo stesso problema e ho capito che stava accadendo perché non stavo impostando il controller della vista radice nella finestra della mia applicazione.
Quello UIViewController
in cui avevo implementato preferredStatusBarStyle
era usato in a UITabBarController
, che controllava l'aspetto delle viste sullo schermo.
Quando ho impostato il controller della vista principale per puntare a questo UITabBarController
, le modifiche alla barra di stato hanno iniziato a funzionare correttamente, come previsto (e il preferredStatusBarStyle
metodo veniva chiamato).
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
... // other view controller loading/setup code
self.window.rootViewController = rootTabBarController;
[self.window makeKeyAndVisible];
return YES;
}
In alternativa, puoi chiamare uno dei seguenti metodi, a seconda dei casi, in ciascuno dei tuoi controller di visualizzazione, a seconda del colore di sfondo, invece di dover usare setNeedsStatusBarAppearanceUpdate
:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
o
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
Nota che dovrai anche impostare UIViewControllerBasedStatusBarAppearance
su NO
nel file plist se usi questo metodo.
setNeedsStatusBarAppearanceUpdate
: i miei sospetti sono stati confermati quando ho apportato questa modifica.
Per chiunque utilizzi un UINavigationController:
Il UINavigationController
non inoltra le preferredStatusBarStyle
chiamate ai controller della vista figlio. Invece gestisce il proprio stato - come dovrebbe, sta disegnando nella parte superiore dello schermo in cui vive la barra di stato e quindi dovrebbe esserne responsabile. Pertanto attuazionepreferredStatusBarStyle
nei VC all'interno di un controller di navigazione non farà nulla, non verranno mai chiamati.
Il trucco è ciò che gli UINavigationController
usi per decidere per cosa restituire UIStatusBarStyleDefault
o UIStatusBarStyleLightContent
. Basa questo sul suo UINavigationBar.barStyle
. Il predefinito (UIBarStyleDefault
) indica la UIStatusBarStyleDefault
barra di stato in primo piano scuro . E UIBarStyleBlack
darà aUIStatusBarStyleLightContent
barra di stato.
TL; DR:
Se vuoi UIStatusBarStyleLightContent
un UINavigationController
uso:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
preferredStatusBarStyle
verrà effettivamente chiamato sul controller di visualizzazione figlio se si nasconde la barra di navigazione (impostata navigationBarHidden
su YES
), esattamente come appropriato.
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
set to YES
avrà effettivamente preferredStatusBarStyle
chiamato, e un avvertimento per quelli che potrebbero inciampare su questo: funziona con navigationBarHidden
, ma non con navigationBar.hidden
!
Quindi ho effettivamente aggiunto una categoria a UINavigationController ma ho usato i metodi:
-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;
e questi hanno restituito l'attuale UIViewController visibile. Ciò consente all'attuale controller di visualizzazione visibile di impostare il proprio stile / visibilità preferito.
Ecco uno snippet di codice completo per questo:
In Swift:
extension UINavigationController {
public override func childViewControllerForStatusBarHidden() -> UIViewController? {
return self.topViewController
}
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return self.topViewController
}
}
In Objective-C:
@interface UINavigationController (StatusBarStyle)
@end
@implementation UINavigationController (StatusBarStyle)
-(UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
-(UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}
@end
E per buona misura, ecco come viene implementato quindi in un UIViewController:
In Swift
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func prefersStatusBarHidden() -> Bool {
return false
}
In Objective-C
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // your own style
}
- (BOOL)prefersStatusBarHidden {
return NO; // your own visibility code
}
Infine, assicurati che il tuo plist dell'app NON abbia "Visualizza aspetto barra di stato basata sul controller" impostato su NO. O eliminare quella linea o impostarla su SÌ (che credo sia l'impostazione predefinita ora per iOS 7?)
return self.topViewController;
return self.visibleViewController;
super
questo metodo e in realtà si desidera modificare il comportamento di tutti i controller di questo tipo
Per chiunque abbia ancora problemi con questo, questa semplice estensione in rapido dovrebbe risolvere il problema per te.
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
}
La mia app ha usato tutti e tre: UINavigationController
, UISplitViewController
, UITabBarController
, quindi questi tutti sembrano prendere il controllo sopra la barra di stato e causerà preferedStatusBarStyle
di non essere chiamati per i loro figli. Per ignorare questo comportamento, puoi creare un'estensione come il resto delle risposte ha menzionato. Ecco un'estensione per tutti e tre, in Swift 4. Vorrei che Apple fosse più chiara su questo genere di cose.
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
extension UISplitViewController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
Modifica: aggiornamento per le modifiche dell'API Swift 4.2
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
extension UISplitViewController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
La risposta di Tyson è corretta per cambiare il colore della barra di stato in biancoUINavigationController
.
Se qualcuno vuole ottenere lo stesso risultato scrivendo il codice, AppDelegate
allora usa il codice qui sotto e scrivilo dentroAppDelegate's
didFinishLaunchingWithOptions
metodo.
E non dimenticate di impostare l' UIViewControllerBasedStatusBarAppearance
aYES
nel file .plist, altrimenti la modifica non rifletterà.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// status bar appearance code
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
return YES;
}
Su un UINavigationController, preferredStatusBarStyle
non viene chiamato perché topViewController
è preferito self
. Quindi, per essere preferredStatusBarStyle
chiamato su un UINavigationController, devi cambiarlochildViewControllerForStatusBarStyle
.
Sostituisci il tuo UINavigationController nella tua classe:
class MyRootNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Per farlo per tutti gli UINavigationController, è possibile ignorare un'estensione (avviso: riguarda UIDocumentPickerViewController, UIImagePickerController, ecc.), Ma probabilmente non dovresti farlo secondo la documentazione di Swift :
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
open override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Oltre alla risposta di Serenn, se stai presentando un controller di visualizzazione con modalPresentationStyle
(ad esempio .overCurrentContext
), dovresti anche chiamarlo sul controller di visualizzazione appena presentato:
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
Non dimenticare di sostituire anche il preferredStatusBarStyle
controller di visualizzazione presentato.
Un'aggiunta alla risposta di Ippona: se stai usando un UINavigationController, probabilmente è meglio aggiungere una categoria:
// 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
Quella soluzione è probabilmente meglio che passare a comportamenti presto deprecati.
preferredStatusBarStyle
e fa la logica specifica di UINavigationController. In questo momento questa logica si basa navigationBar.barStyle
ma posso vedere ulteriori controlli aggiunti (ad es. UISearchDisplayController
Passare alla modalità di navigazione della barra di navigazione). Sostituendo la logica predefinita perdi tutte queste funzionalità e ti lasci aperto per fastidiosi momenti "wtf" in futuro. Vedi la mia risposta sopra per il modo corretto di farlo pur supportando il comportamento del controller di navigazione integrato.
Come menzionato nella risposta selezionata , la causa principale è controllare l'oggetto controller della vista radice della finestra.
childForStatusBarStyle
Utilizza le seguenti estensioni, gestisce tutti gli scenari sopra indicati -
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController?.childForStatusBarStyle ?? selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return topViewController?.childForStatusBarStyle ?? topViewController
}
}
extension AppRootViewController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return children.first { $0.childForStatusBarStyle != nil }?.childForStatusBarStyle?.preferredStatusBarStyle ?? .default
}
}
UIViewControllerBasedStatusBarAppearance
digitare info.plist
come vero per impostazione predefinitaSe si presenta il nuovo flusso in modo modale, si stacca dal flusso di stile della barra di stato esistente. Supponiamo quindi che tu stia presentando un NewFlowUIViewController
e quindi aggiungi un nuovo controller di navigazione o tabBar a NewFlowUIViewController
, quindi aggiungi l'estensione di NewFlowUIViewController
anche per gestire ulteriormente lo stile della barra di stato del controller.
Se si imposta modalPresentationStyle diverso da fullScreen
quando si presenta in modalità modale, è necessario impostare modalPresentationCapturesStatusBarAppearance
su true in modo che il controller di visualizzazione presentato debba ricevere il controllo dell'aspetto della barra di stato.
UINavigationController
è una sottoclasse di UIViewController
(chi lo sapeva 🙃)!
Pertanto, quando si presentano controller di visualizzazione incorporati nei controller di navigazione, non si presentano realmente i controller di visualizzazione incorporati; stai presentando i controller di navigazione! UINavigationController
, come sottoclasse di UIViewController
, eredita preferredStatusBarStyle
echildForStatusBarStyle
, che è possibile impostare come desiderato.
Uno dei seguenti metodi dovrebbe funzionare:
info.plist
, aggiungi la seguente proprietà:
UIUserInterfaceStyle
(alias "Stile interfaccia utente")Ignora preferredStatusBarStyle
dentroUINavigationController
preferredStatusBarStyle
( doc ) - Lo stile preferito della barra di stato per il controller di visualizzazioneSottoclasse o estensione UINavigationController
class MyNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
O
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
Ignora childForStatusBarStyle
dentroUINavigationController
childForStatusBarStyle
( doc ): chiamato quando il sistema deve utilizzare il controller di visualizzazione per determinare lo stile della barra di stato"Se il controller della vista contenitore deriva il suo stile dalla barra di stato da uno dei controller della vista figlio, [sovrascrivi questa proprietà] e restituisce quel controller vista figlio. Se restituisci zero o non ignori questo metodo, viene utilizzato lo stile della barra di stato per sé Se il valore restituito da questo metodo cambia, chiama il metodo setNeedsStatusBarAppearanceUpdate (). "
Sottoclasse o estensione UINavigationController
class MyNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
O
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
Puoi restituire qualsiasi controller di visualizzazione che desideri sopra. Raccomando una delle seguenti:
topViewController
(of UINavigationController
) ( doc ) - Il controller di visualizzazione nella parte superiore dello stack di navigazionevisibleViewController
(of UINavigationController
) ( doc ) - Il controller di vista associato alla vista attualmente visibile nell'interfaccia di navigazione (suggerimento: questo può includere "un controller di vista che è stato presentato modalmente sopra il controller di navigazione stesso")Nota: se decidi di effettuare una sottoclasse UINavigationController
, ricorda di applicare quella classe ai tuoi controllori di navigazione tramite l'ispettore identità in IB.
PS Il mio codice utilizza la sintassi di Swift 5.1 😎
@ di serenn risposta di sopra è ancora ottima per il caso di UINavigationController. Tuttavia, per swift 3 le funzioni childViewController sono state modificate in vars
. Quindi il UINavigationController
codice di estensione dovrebbe essere:
override open var childViewControllerForStatusBarStyle: UIViewController? {
return topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return topViewController
}
E poi nel controller della vista che dovrebbe dettare lo stile della barra di stato:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Se viewController è in UINavigationController.
Sottoclasse UINavigationController e aggiungi
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
preferredStatusBarStyle
Verrà chiamato ViewController .
UIStatusBarStyle in iOS 7
La barra di stato in iOS 7 è trasparente, la vista dietro mostra attraverso.
Lo stile della barra di stato si riferisce alle apparenze del suo contenuto. In iOS 7, il contenuto della barra di stato è scuro ( UIStatusBarStyleDefault
) o chiaro ( UIStatusBarStyleLightContent
). Entrambi UIStatusBarStyleBlackTranslucent
e UIStatusBarStyleBlackOpaque
sono deprecati in iOS 7.0. Usa UIStatusBarStyleLightContent
invece.
Come cambiare UIStatusBarStyle
Se sotto la barra di stato è presente una barra di navigazione, lo stile della barra di stato verrà adattato allo stile della barra di navigazione ( UINavigationBar.barStyle
):
In particolare, se lo stile della barra di navigazione è UIBarStyleDefault, lo stile della barra di stato sarà UIStatusBarStyleDefault
; se lo stile della barra di navigazione è UIBarStyleBlack
, lo sarà lo stile della barra di statoUIStatusBarStyleLightContent
.
Se non esiste una barra di navigazione sotto la barra di stato, lo stile della barra di stato può essere controllato e modificato da un controller di visualizzazione individuale mentre l'app è in esecuzione.
- [UIViewController preferredStatusBarStyle]
è un nuovo metodo aggiunto in iOS 7. Può essere sostituito per restituire lo stile preferito della barra di stato:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Se lo stile della barra di stato deve essere controllato da un controller di visualizzazione figlio anziché da sé, eseguire l'override -[UIViewController childViewControllerForStatusBarStyle]
l' per restituire quel controller di visualizzazione figlio.
Se si preferisce rinunciare a questo comportamento e impostare lo stile della barra di stato utilizzando il -[UIApplication statusBarStyle]
metodo, aggiungere la UIViewControllerBasedStatusBarAppearance
chiave al Info.plist
file di un'app e assegnargli il valore NO.
Se qualcuno utilizza un controller di navigazione e desidera che tutti i controller di navigazione abbiano lo stile nero, puoi scrivere un'estensione su UINavigationController come questa in Swift 3 e si applicherà a tutti i controller di navigazione (invece di assegnarlo a un controller in un tempo).
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.barStyle = UIBarStyle.black
}
}
In Swift per qualsiasi tipo di UIViewController:
Nel tuo AppDelegate
set:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootController
può essere di qualsiasi tipo UIViewController
, ad esempio UITabBarController
o UINavigationController
.
Quindi, sovrascrivi questo controller di root in questo modo:
class RootController: UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
Ciò modificherà l'aspetto della barra di stato nell'intera app, poiché il controller di root è l'unico responsabile dell'aspetto della barra di stato.
Ricorda di impostare la proprietà View controller-based status bar appearance
su YES nel tuo Info.plist
per farlo funzionare (che è l'impostazione predefinita).
La maggior parte delle risposte non include una buona implementazione del childViewControllerForStatusBarStyle
metodo per UINavigationController
. Secondo la mia esperienza, dovresti gestire casi come quando il controller di visualizzazione trasparente viene presentato sul controller di navigazione. In questi casi dovresti passare il controllo al tuo controller modale ( visibleViewController
), ma non quando sta scomparendo.
override var childViewControllerForStatusBarStyle: UIViewController? {
var childViewController = visibleViewController
if let controller = childViewController, controller.isBeingDismissed {
childViewController = topViewController
}
return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
Come per iOS 13.4 il preferredStatusBarStyle
metodo inUINavigationController
categoria non verrà chiamato, lo swizzling sembra essere l'unica opzione senza la necessità di utilizzare una sottoclasse.
Esempio:
Intestazione di categoria:
@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end
Implementazione:
#import "UINavigationController+StatusBarStyle.h"
#import <objc/runtime.h>
@implementation UINavigationController (StatusBarStyle)
void (^swizzle)(Class, SEL, SEL) = ^(Class c, SEL orig, SEL new){
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
};
+ (void)setUseLightStatusBarStyle {
swizzle(self.class, @selector(preferredStatusBarStyle), @selector(_light_preferredStatusBarStyle));
}
- (UIStatusBarStyle)_light_preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
@end
Utilizzo in AppDelegate.h:
#import "UINavigationController+StatusBarStyle.h"
[UINavigationController setUseLightStatusBarStyle];
Ecco il mio metodo per risolvere questo.
Definire un protocollo chiamato AGViewControllerAppearance .
AGViewControllerAppearance.h
#import <Foundation/Foundation.h>
@protocol AGViewControllerAppearance <NSObject>
@optional
- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;
@end
Definire una categoria su UIViewController chiamata 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
Ora è il momento di dire che il controller di visualizzazione sta implementando AGViewControllerAppearance protocollo .
Esempio:
@interface XYSampleViewController () <AGViewControllerAppearance>
... the rest of the interface
@end
Naturalmente, è possibile implementare il resto dei metodi ( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) dal protocollo e UIViewController + upgrade farà la personalizzazione adeguata in base ai valori forniti da loro.
Si noti che quando si utilizza il self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
soluzione
assicurati di andare al tuo plist e impostare "Visualizza aspetto della barra di stato basata sul controller" su SÌ. Se è NO non funzionerà.
Da Xcode 11.4, sovrascrivendo il preferredStatusBarStyle
proprietà in un'estensione UINavigationController non funziona più poiché non verrà chiamata.
L'impostazione di barStyle
di navigationBar
su .black
funziona davvero, ma ciò aggiungerà effetti collaterali indesiderati se aggiungi viste secondarie alla barra di navigazione che possono avere aspetti diversi per la modalità chiara e scura. Perché impostando il barStyle
nero su, la userInterfaceStyle
vista di quella che è incorporata nella barra di navigazione avrà sempre userInterfaceStyle.dark
indipendentemente userInterfaceStyle
dall'app.
La soluzione corretta che mi viene in mente è aggiungendo una sottoclasse di UINavigationController
e l'override preferredStatusBarStyle
lì. Se poi usi questo UINavigationController personalizzato per tutte le tue visualizzazioni, sarai sul lato di salvataggio.
NavigationController o TabBarController sono quelli che devono fornire lo stile. Ecco come ho risolto: https://stackoverflow.com/a/39072526/242769