Ś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 UIViewController
którym wdrożyłem preferredStatusBarStyle
był 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 preferredStatusBarStyle
wywoł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ć UIViewControllerBasedStatusBarAppearance
na NO
plik plist, jeśli używasz tej metody.
setNeedsStatusBarAppearanceUpdate
- moje podejrzenia zostały potwierdzone, kiedy dokonałem tej zmiany.
Dla wszystkich korzystających z UINavigationController:
UINavigationController
Nie do przodu na preferredStatusBarStyle
rozmowy 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 preferredStatusBarStyle
w VC w kontrolerze nawigacyjnym nic nie zrobi - nigdy nie zostanie wywołana.
Sztuką jest to, czego UINavigationController
używa, aby zdecydować, po co zwrócić UIStatusBarStyleDefault
lub UIStatusBarStyleLightContent
. Opiera to na swoim UINavigationBar.barStyle
. Ustawienie domyślne ( UIBarStyleDefault
) powoduje wyświetlenie ciemnego UIStatusBarStyleDefault
paska stanu pierwszego planu . I UIBarStyleBlack
da UIStatusBarStyleLightContent
pasek stanu.
TL; DR:
Jeśli chcesz UIStatusBarStyleLightContent
w UINavigationController
użyciu:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
preferredStatusBarStyle
w rzeczywistości zostanie wywołany na kontrolerze widoku potomnego, jeśli ukryjesz pasek nawigacji (ustawiony navigationBarHidden
na YES
), dokładnie tak, jak to właściwe.
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
zestaw do YES
rzeczywiście preferredStatusBarStyle
zadzwonił, 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
super
tej 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 preferedStatusBarStyle
aby 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, AppDelegate
użyj poniższego kodu i zapisz go w środkuAppDelegate's
didFinishLaunchingWithOptions
metody.
I nie zapomnij ustawić UIViewControllerBasedStatusBarAppearance
naYES
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 preferredStatusBarStyle
nie jest wywoływany, ponieważ topViewController
jest preferowany self
. Aby więc zostać preferredStatusBarStyle
wywoł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ć preferredStatusBarStyle
przedstawionego 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.
preferredStatusBarStyle
i wykonuje logikę specyficzną dla UINavigationController. Obecnie ta logika jest oparta, navigationBar.barStyle
ale widzę, że dodawane są dodatkowe kontrole (np. UISearchDisplayController
Przejś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
}
}
UIViewControllerBasedStatusBarAppearance
klucza, info.plist
ponieważ 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 NewFlowUIViewController
a następnie dodajesz nowy kontroler nawigacji lub tabBar do NewFlowUIViewController
, a następnie dodajesz również rozszerzenie, NewFlowUIViewController
aby zarządzać dalszym stylem paska stanu kontrolera.
Jeśli ustawisz modalPresentationStyle inaczej niż fullScreen
podczas prezentacji modalnej, musisz ustawić wartość modalPresentationCapturesStatusBarAppearance
true, 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 UIViewController
dziedziczy preferredStatusBarStyle
ichildForStatusBarStyle
, 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 preferredStatusBarStyle
w 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 childForStatusBarStyle
w 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 UINavigationController
kod 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 preferredStatusBarStyle
zostanie 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 UIStatusBarStyleBlackTranslucent
i UIStatusBarStyleBlackOpaque
są 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 UIViewControllerBasedStatusBarAppearance
klucz do pliku aplikacji Info.plist
i 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 AppDelegate
zestawie:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootController
może być dowolnego rodzaju UIViewController
, np . UITabBarController
lub 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 appearance
na TAK, Info.plist
aby ta funkcja działała (co jest ustawieniem domyślnym).
Większość odpowiedzi nie obejmuje dobrej implementacji childViewControllerForStatusBarStyle
metody 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 preferredStatusBarStyle
metoda 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 barStyle
z navigationBar
do .black
prac 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 barStyle
czarny spowoduje, że userInterfaceStyle
widok osadzony w pasku nawigacji będzie zawsze miał userInterfaceStyle.dark
niezależnie od userInterfaceStyle
aplikacji.
Właściwym rozwiązaniem, które wymyślam, jest dodanie podklasy UINavigationController
i 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