Śledziłem ten wątek, aby go zastąpić -preferredStatusBarStyle, ale nie jest on wywoływany. Czy są jakieś opcje, które mogę zmienić, aby to włączyć? (Używam XIB w moim projekcie).
Śledziłem ten wątek, aby go zastąpić -preferredStatusBarStyle, ale nie jest on wywoływany. Czy są jakieś opcje, które mogę zmienić, aby to włączyć? (Używam XIB w moim projekcie).
Odpowiedzi:
Miałem ten sam problem i zorientowałem się, że tak się dzieje, ponieważ nie ustawiałem kontrolera widoku głównego w oknie aplikacji.
W UIViewControllerktórym wdrożyłem preferredStatusBarStylebył używany w UITabBarController, który kontrolował wygląd widoków na ekranie.
Kiedy ustawiłem kontroler widoku głównego, aby wskazywał na to UITabBarController, zmiany paska stanu zaczęły działać poprawnie, zgodnie z oczekiwaniami (i preferredStatusBarStylewywołano metodę).
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
... // other view controller loading/setup code
self.window.rootViewController = rootTabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Alternatywnie możesz wywołać jedną z następujących metod, odpowiednio, w każdym z kontrolerów widoku, w zależności od koloru tła, zamiast konieczności używania setNeedsStatusBarAppearanceUpdate:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
lub
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
Pamiętaj, że musisz również ustawić UIViewControllerBasedStatusBarAppearancena NOplik plist, jeśli używasz tej metody.
setNeedsStatusBarAppearanceUpdate- moje podejrzenia zostały potwierdzone, kiedy dokonałem tej zmiany.
Dla wszystkich korzystających z UINavigationController:
UINavigationControllerNie do przodu na preferredStatusBarStylerozmowy do jej zdaniem dziecko kontrolerów. Zamiast tego zarządza swoim własnym stanem - tak jak powinien, rysuje u góry ekranu, na którym znajduje się pasek stanu, i dlatego powinien być za to odpowiedzialny. W związku z tym implementacja preferredStatusBarStylew VC w kontrolerze nawigacyjnym nic nie zrobi - nigdy nie zostanie wywołana.
Sztuką jest to, czego UINavigationControllerużywa, aby zdecydować, po co zwrócić UIStatusBarStyleDefaultlub UIStatusBarStyleLightContent. Opiera to na swoim UINavigationBar.barStyle. Ustawienie domyślne ( UIBarStyleDefault) powoduje wyświetlenie ciemnego UIStatusBarStyleDefaultpaska stanu pierwszego planu . I UIBarStyleBlackda UIStatusBarStyleLightContentpasek stanu.
TL; DR:
Jeśli chcesz UIStatusBarStyleLightContentw UINavigationControllerużyciu:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
preferredStatusBarStylew rzeczywistości zostanie wywołany na kontrolerze widoku potomnego, jeśli ukryjesz pasek nawigacji (ustawiony navigationBarHiddenna YES), dokładnie tak, jak to właściwe.
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHiddenzestaw do YESrzeczywiście preferredStatusBarStylezadzwonił, oraz ostrzeżenie dla tych, którzy mogą się na to natknąć: działa z navigationBarHidden, ale nie z navigationBar.hidden!
Więc faktycznie dodałem kategorię do UINavigationController, ale użyłem metod:
-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;
i sprawiły, że zwracają bieżący widoczny UIViewController. Dzięki temu bieżący kontroler widoku widocznego może ustawić własny preferowany styl / widoczność.
Oto pełny fragment kodu:
W Swift:
extension UINavigationController {
public override func childViewControllerForStatusBarHidden() -> UIViewController? {
return self.topViewController
}
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return self.topViewController
}
}
W celu C:
@interface UINavigationController (StatusBarStyle)
@end
@implementation UINavigationController (StatusBarStyle)
-(UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
-(UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}
@end
I na dokładkę, oto jak jest to zaimplementowane następnie w UIViewController:
W Swift
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func prefersStatusBarHidden() -> Bool {
return false
}
W celu C
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // your own style
}
- (BOOL)prefersStatusBarHidden {
return NO; // your own visibility code
}
Na koniec upewnij się, że lista aplikacji NIE ma ustawienia „Wyświetl pasek stanu oparty na kontrolerze” ustawionego na NIE. Usuń tę linię lub ustaw ją na TAK (która, jak sądzę, jest teraz domyślna dla iOS 7?)
return self.topViewController;działa dla mnie, ale return self.visibleViewController;- nie
supertej metody i naprawdę chcesz zmienić zachowanie wszystkich kontrolerów tego typu
Dla każdego, kto wciąż zmaga się z tym, to proste rozszerzenie w trybie szybkim powinno rozwiązać problem.
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
}
Moja aplikacja stosować wszystkie trzy: UINavigationController, UISplitViewController, UITabBarController, a więc wszystkie one wydają się przejąć kontrolę nad pasku stanu i spowoduje preferedStatusBarStyleaby nie nazwać ich dzieci. Aby zastąpić to zachowanie, możesz utworzyć rozszerzenie takie, jak wspomniano w pozostałych odpowiedziach. Oto rozszerzenie dla wszystkich trzech, w Swift 4. Szkoda, że Apple nie wyjaśniło tego rodzaju rzeczy.
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
}
}
Edycja: aktualizacja zmian interfejsu 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
}
}
Odpowiedź Tysona jest poprawna w przypadku zmiany koloru paska stanu na białyUINavigationController .
Jeśli ktoś chce osiągnąć ten sam wynik, wpisując kod, AppDelegateużyj poniższego kodu i zapisz go w środkuAppDelegate's didFinishLaunchingWithOptions metody.
I nie zapomnij ustawić UIViewControllerBasedStatusBarAppearancenaYES w pliku .plist, inaczej zmiana nie będzie odzwierciedlać.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// status bar appearance code
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
return YES;
}
Na UINavigationController preferredStatusBarStylenie jest wywoływany, ponieważ topViewControllerjest preferowany self. Aby więc zostać preferredStatusBarStylewywołanym na UINavigationController, musisz go zmienićchildViewControllerForStatusBarStyle .
Zastąp swój UINavigationController w swojej klasie:
class MyRootNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Aby to zrobić dla wszystkich UINavigationController, możesz przesłonić rozszerzenie (ostrzeżenie: wpływa na UIDocumentPickerViewController, UIImagePickerController itp.), Ale prawdopodobnie nie powinieneś tego robić zgodnie z dokumentacją Swift :
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
open override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Oprócz odpowiedzi serenn, jeśli prezentujesz kontrolerowi widoku modalPresentationStyle(na przykład .overCurrentContext), powinieneś także wywołać to na nowo przedstawionym kontrolerze widoku:
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
Nie zapomnij również zastąpić preferredStatusBarStyleprzedstawionego kontrolera widoku.
Dodatek do odpowiedzi Hippo: jeśli używasz UINavigationController, prawdopodobnie lepiej jest dodać kategorię:
// 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
To rozwiązanie jest prawdopodobnie lepsze niż przejście na przestarzałe zachowanie.
preferredStatusBarStylei wykonuje logikę specyficzną dla UINavigationController. Obecnie ta logika jest oparta, navigationBar.barStyleale widzę, że dodawane są dodatkowe kontrole (np. UISearchDisplayControllerPrzejście do ukrycia trybu paska nawigacyjnego). Przesłaniając domyślną logikę tracisz całą tę funkcjonalność i pozostawiasz się otwarty na irytujące momenty w przyszłości. Zobacz moją odpowiedź powyżej, aby dowiedzieć się, jak to zrobić, jednocześnie obsługując wbudowane zachowanie kontrolera nawigacyjnego.
Jak wspomniano w wybranej odpowiedzi , główną przyczyną jest sprawdzenie obiektu kontrolera widoku głównego okna.
childForStatusBarStyle Użyj następujących rozszerzeń, obsługuje wszystkie powyższe scenariusze -
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
}
}
UIViewControllerBasedStatusBarAppearanceklucza, info.plistponieważ domyślnie jest to prawdaW przypadku modalnego przedstawienia nowego przepływu, odłącza się on od istniejącego przepływu w stylu paska stanu. Załóżmy, że prezentujesz NewFlowUIViewControllera następnie dodajesz nowy kontroler nawigacji lub tabBar do NewFlowUIViewController, a następnie dodajesz również rozszerzenie, NewFlowUIViewControlleraby zarządzać dalszym stylem paska stanu kontrolera.
Jeśli ustawisz modalPresentationStyle inaczej niż fullScreenpodczas prezentacji modalnej, musisz ustawić wartość modalPresentationCapturesStatusBarAppearancetrue, aby prezentowany kontroler widoku otrzymał kontrolę wyglądu paska stanu.
UINavigationController jest podklasą UIViewController (kto wiedział 🙃)!
Dlatego prezentując kontrolery widoku osadzone w kontrolerach nawigacji, tak naprawdę nie prezentujesz wbudowanych kontrolerów widoku; prezentujesz kontrolery nawigacyjne! UINavigationController, jako podklasa UIViewControllerdziedziczy preferredStatusBarStyleichildForStatusBarStyle , którą można ustawić według potrzeb.
Każda z poniższych metod powinna działać:
info.plist dodaj następującą właściwość:
UIUserInterfaceStyle (inaczej. „Styl interfejsu użytkownika”)Zastąp preferredStatusBarStylew ciąguUINavigationController
preferredStatusBarStyle( doc ) - Preferowany styl paska stanu dla kontrolera widokuPodklasa lub rozszerzenie UINavigationController
class MyNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
LUB
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}Zastąp childForStatusBarStylew ciąguUINavigationController
childForStatusBarStyle( dok ) - Wywoływany, gdy system potrzebuje kontrolera widoku do określania stylu paska stanu„Jeśli kontroler widoku kontenera wywodzi swój styl paska stanu z jednego ze swoich kontrolerów widoku potomnego, [zastąp tę właściwość] i zwróć ten kontroler widoku potomnego. Jeśli zwrócisz zero lub nie zastąpisz tej metody, użyty zostanie styl paska stanu dla siebie . Jeśli wartość zwracana z tej metody ulegnie zmianie, wywołaj metodę setNeedsStatusBarAppearanceUpdate (). "
Podklasa lub rozszerzenie UINavigationController
class MyNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
LUB
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
topViewController
}
}Możesz zwrócić dowolny kontroler widoku, który chcesz powyżej. Polecam jedno z poniższych:
topViewController(z UINavigationController) ( dok ) - Kontroler widoku u góry stosu nawigacjivisibleViewController(of UINavigationController) ( doc ) - Kontroler widoku skojarzony z aktualnie widocznym widokiem w interfejsie nawigacyjnym (wskazówka: może to obejmować „kontroler widoku, który został przedstawiony modalnie na samym kontrolerze nawigacyjnym”)Uwaga: Jeśli zdecydujesz się na podklasę UINavigationController, pamiętaj o zastosowaniu tej klasy do kontrolerów nawigacyjnych za pośrednictwem inspektora tożsamości w IB.
PS Mój kod używa składni Swift 5.1 😎
Powyższa odpowiedź @ serenn jest nadal świetna w przypadku UINavigationControllers. Jednak w swift 3 funkcje childViewController zostały zmienione na vars. Zatem UINavigationControllerkod rozszerzenia powinien być:
override open var childViewControllerForStatusBarStyle: UIViewController? {
return topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return topViewController
}
A następnie w kontrolerze widoku, który powinien dyktować styl paska stanu:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Jeśli Twój viewController znajduje się w obszarze UINavigationController.
Podklasa UINavigationController i dodaj
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
ViewController preferredStatusBarStylezostanie wywołany.
UIStatusBarStyle w iOS 7
Pasek stanu w iOS 7 jest przezroczysty, widać za nim widok.
Styl paska stanu odnosi się do wyglądu jego zawartości. W iOS 7 zawartość paska stanu jest ciemna ( UIStatusBarStyleDefault) lub jasna ( UIStatusBarStyleLightContent). Zarówno UIStatusBarStyleBlackTranslucenti UIStatusBarStyleBlackOpaquesą przestarzałe w iOS 7.0. Posługiwać sięUIStatusBarStyleLightContent zamiast tego.
Jak zmienić UIStatusBarStyle
Jeśli poniżej paska stanu znajduje się pasek nawigacji, styl paska stanu zostanie dopasowany do stylu paska nawigacji (UINavigationBar.barStyle ):
W szczególności, jeśli stylem paska nawigacji jest UIBarStyleDefault, stylem paska stanu będzie UIStatusBarStyleDefault; jeśli stylem paska nawigacji jest UIBarStyleBlack, stylem paska stanu będzieUIStatusBarStyleLightContent .
Jeśli pod paskiem stanu nie ma paska nawigacji, styl paska stanu może być kontrolowany i zmieniany przez indywidualny kontroler widoku podczas działania aplikacji.
- [UIViewController preferredStatusBarStyle]to nowa metoda dodana w iOS 7. Można ją zastąpić, aby zwrócić preferowany styl paska stanu:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Jeśli styl paska stanu powinien być kontrolowany przez kontroler widoku potomnego zamiast siebie, zastąp -[UIViewController childViewControllerForStatusBarStyle] aby zwrócić ten kontroler widoku potomnego.
Jeśli wolisz zrezygnować z tego zachowania i ustawić styl paska stanu za pomocą -[UIApplication statusBarStyle]metody, dodaj UIViewControllerBasedStatusBarAppearanceklucz do pliku aplikacji Info.plisti nadaj mu wartość NIE.
Jeśli ktoś używa kontrolera nawigacyjnego i chce, aby wszystkie kontrolery nawigacyjne miały czarny styl, możesz napisać rozszerzenie do UINavigationController w ten sposób w Swift 3 i będzie ono dotyczyło wszystkich kontrolerów nawigacyjnych (zamiast przypisywać je do jednego kontrolera na czas).
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.barStyle = UIBarStyle.black
}
}
W Swift dla dowolnego rodzaju UIViewController:
W twoim AppDelegatezestawie:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootControllermoże być dowolnego rodzaju UIViewController, np . UITabBarControllerlub UINavigationController.
Następnie zastąp ten kontroler root w następujący sposób:
class RootController: UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
Spowoduje to zmianę wyglądu paska stanu w całej aplikacji, ponieważ kontroler root ponosi wyłączną odpowiedzialność za wygląd paska stanu.
Pamiętaj, aby ustawić właściwość View controller-based status bar appearancena TAK, Info.plistaby ta funkcja działała (co jest ustawieniem domyślnym).
Większość odpowiedzi nie obejmuje dobrej implementacji childViewControllerForStatusBarStylemetody dla UINavigationController. Zgodnie z moim doświadczeniem powinieneś poradzić sobie z takimi przypadkami, jak wyświetlanie kontrolera przezroczystego nad kontrolerem nawigacyjnym. W takich przypadkach powinieneś przekazać kontrolę swojemu kontrolerowi modalnemu ( visibleViewController), ale nie wtedy, gdy znika.
override var childViewControllerForStatusBarStyle: UIViewController? {
var childViewController = visibleViewController
if let controller = childViewController, controller.isBeingDismissed {
childViewController = topViewController
}
return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
Jak w iOS 13.4 preferredStatusBarStylemetoda wUINavigationController kategorii nie będzie wywoływana, swizzling wydaje się być jedyną opcją bez potrzeby używania podklasy.
Przykład:
Nagłówek kategorii:
@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end
Realizacja:
#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
Zastosowanie w AppDelegate.h:
#import "UINavigationController+StatusBarStyle.h"
[UINavigationController setUseLightStatusBarStyle];
Oto moja metoda rozwiązania tego problemu.
Zdefiniuj protokół o nazwie AGViewControllerAppearance .
AGViewControllerAppearance.h
#import <Foundation/Foundation.h>
@protocol AGViewControllerAppearance <NSObject>
@optional
- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;
@end
Zdefiniuj kategorię w UIViewController o nazwie 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
Czas powiedzieć, że kontroler widoku implementuje wygląd AGViewController protokół .
Przykład:
@interface XYSampleViewController () <AGViewControllerAppearance>
... the rest of the interface
@end
Oczywiście, można zaimplementować resztę metod ( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) od protokołu i UIViewController + Upgrade zrobi właściwego dostosowania na podstawie wartości dostarczonych przez nich.
Pamiętaj, że podczas korzystania z self.navigationController.navigationBar.barStyle = UIBarStyleBlack; rozwiązania
koniecznie przejdź do swojej listy i ustaw „Wyświetl wygląd paska stanu kontrolera” na TAK. Jeśli NIE, to nie będzie działać.
Od Xcode 11.4, zastępowanie preferredStatusBarStyle właściwości w rozszerzeniu UINavigationController nie działa już, ponieważ nie zostanie wywołane.
Ustawianie barStylez navigationBardo .blackprac rzeczywiście ale to doda niepożądane skutki uboczne, jeśli dodać subviews do navigationBar które mogą mieć różny wygląd w trybie jasnym i ciemnym. Ponieważ ustawienie na barStyleczarny spowoduje, że userInterfaceStylewidok osadzony w pasku nawigacji będzie zawsze miał userInterfaceStyle.darkniezależnie od userInterfaceStyleaplikacji.
Właściwym rozwiązaniem, które wymyślam, jest dodanie podklasy UINavigationControlleri zastąpienie go preferredStatusBarStyle. Jeśli następnie użyjesz tego niestandardowego kontrolera UINavigationController dla wszystkich swoich widoków, będziesz po stronie zapisywania.
NavigationController lub TabBarController to te, które muszą podać styl. Oto jak rozwiązałem: https://stackoverflow.com/a/39072526/242769