Ich bin diesem Thread gefolgt , um -preferredStatusBarStyle
ihn zu überschreiben , aber er wird nicht aufgerufen. Gibt es Optionen, die ich ändern kann, um sie zu aktivieren? (Ich verwende XIBs in meinem Projekt.)
Ich bin diesem Thread gefolgt , um -preferredStatusBarStyle
ihn zu überschreiben , aber er wird nicht aufgerufen. Gibt es Optionen, die ich ändern kann, um sie zu aktivieren? (Ich verwende XIBs in meinem Projekt.)
Antworten:
Ich hatte das gleiche Problem und stellte fest, dass es passierte, weil ich den Root-View-Controller nicht in meinem Anwendungsfenster eingestellt hatte.
Das, UIViewController
in dem ich das implementiert hatte, preferredStatusBarStyle
wurde in einem verwendet UITabBarController
, das das Erscheinungsbild der Ansichten auf dem Bildschirm kontrollierte.
Als ich den Root-View-Controller so einstellte UITabBarController
, dass er darauf hinweist, funktionierten die Änderungen in der Statusleiste wie erwartet ordnungsgemäß (und die preferredStatusBarStyle
Methode wurde aufgerufen).
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
... // other view controller loading/setup code
self.window.rootViewController = rootTabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Alternativ können Sie in jedem Ihrer Ansichts-Controller je nach Hintergrundfarbe eine der folgenden Methoden aufrufen, anstatt sie verwenden zu müssen setNeedsStatusBarAppearanceUpdate
:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
oder
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
Beachten Sie, dass Sie auch Set benötigen , UIViewControllerBasedStatusBarAppearance
um NO
in der plist - Datei , wenn Sie diese Methode verwenden.
setNeedsStatusBarAppearanceUpdate
- mein Verdacht wurde bestätigt, als ich diese Änderung vornahm.
Für alle, die einen UINavigationController verwenden:
Der UINavigationController
leitet keine preferredStatusBarStyle
Anrufe an seine untergeordneten Ansichtscontroller weiter. Stattdessen verwaltet es seinen eigenen Status - wie es sollte, zeichnet es am oberen Bildschirmrand, wo sich die Statusleiste befindet, und sollte daher dafür verantwortlich sein. Daher wird die Implementierung preferredStatusBarStyle
in Ihren VCs innerhalb eines Navigationscontrollers nichts bewirken - sie werden niemals aufgerufen.
Der Trick ist, was die UINavigationController
verwendet, um zu entscheiden, was für UIStatusBarStyleDefault
oder zurückgegeben werden soll UIStatusBarStyleLightContent
. Es stützt dies auf seine UINavigationBar.barStyle
. Das default ( UIBarStyleDefault
) führt zur dunklen Vordergrundstatusleiste UIStatusBarStyleDefault
. Und UIBarStyleBlack
gibt eine UIStatusBarStyleLightContent
Statusleiste.
TL; DR:
Wenn Sie UIStatusBarStyleLightContent
eine UINavigationController
Verwendung wünschen :
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
preferredStatusBarStyle
tatsächlich auf dem untergeordneten Ansichtscontroller aufgerufen wird, wenn Sie die Navigationsleiste ( navigationBarHidden
auf YES
) genau entsprechend ausblenden .
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
set to YES
tatsächlich preferredStatusBarStyle
angerufen hat, und eine Warnung an diejenigen, die darüber stolpern könnten: Es funktioniert mit navigationBarHidden
, aber nicht mit navigationBar.hidden
!
Also habe ich UINavigationController tatsächlich eine Kategorie hinzugefügt, aber die folgenden Methoden verwendet:
-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;
und ließ diese den aktuell sichtbaren UIViewController zurückgeben. Auf diese Weise kann der aktuelle Controller für sichtbare Ansichten seinen eigenen bevorzugten Stil / Sichtbarkeit festlegen.
Hier ist ein vollständiger Code-Ausschnitt dafür:
In Swift:
extension UINavigationController {
public override func childViewControllerForStatusBarHidden() -> UIViewController? {
return self.topViewController
}
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return self.topViewController
}
}
In Ziel-C:
@interface UINavigationController (StatusBarStyle)
@end
@implementation UINavigationController (StatusBarStyle)
-(UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
-(UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}
@end
Und hier ist, wie es dann in einem UIViewController implementiert wird:
In Swift
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func prefersStatusBarHidden() -> Bool {
return false
}
In Ziel-C
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // your own style
}
- (BOOL)prefersStatusBarHidden {
return NO; // your own visibility code
}
Stellen Sie schließlich sicher, dass in Ihrer App-Liste NICHT die Option "Controller-basiertes Statusleisten-Erscheinungsbild anzeigen" auf NEIN gesetzt ist. Löschen Sie diese Zeile oder setzen Sie sie auf YES (was ist meiner Meinung nach jetzt die Standardeinstellung für iOS 7?)
return self.topViewController;
funktioniert für mich, aber return self.visibleViewController;
- nicht
super
in dieser Methode , und Sie wollen tatsächlich das Verhalten aller Controller dieser Art zu ändern
Für alle, die immer noch damit zu kämpfen haben, sollte diese einfache Erweiterung in Swift das Problem für Sie beheben.
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
}
Meine app verwendet , um alle drei: UINavigationController
, UISplitViewController
, UITabBarController
, damit alle diese scheinen die Kontrolle über die Statusleiste zu übernehmen und wird dazu führen , preferedStatusBarStyle
nicht für ihre Kinder heißen. Um dieses Verhalten zu überschreiben, können Sie eine Erweiterung erstellen, wie in den übrigen Antworten erwähnt. Hier ist eine Erweiterung für alle drei in Swift 4. Ich wünschte, Apple wäre klarer über diese Art von Dingen.
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
}
}
Bearbeiten: Update für Swift 4.2 API-Änderungen
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
}
}
Tysons Antwort ist richtig, wenn die Farbe der Statusleiste in Weiß geändert wird UINavigationController
.
Wenn jemand das gleiche Ergebnis erzielen möchte, indem er den Code schreibt, AppDelegate
verwenden Sie den folgenden Code und schreiben Sie ihn in die AppDelegate's
didFinishLaunchingWithOptions
Methode.
Und vergessen Sie nicht , die zu setzen , UIViewControllerBasedStatusBarAppearance
um YES
in der .plist - Datei, sonst wird die Änderung nicht widerspiegeln.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// status bar appearance code
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
return YES;
}
Wird auf einem UINavigationController preferredStatusBarStyle
nicht aufgerufen, da dies topViewController
bevorzugt wird self
. Um preferredStatusBarStyle
auf einem UINavigationController aufgerufen zu werden, müssen Sie dessen ändern childViewControllerForStatusBarStyle
.
Überschreiben Sie Ihren UINavigationController in Ihrer Klasse:
class MyRootNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Um dies für alle UINavigationController zu tun, können Sie eine Erweiterung überschreiben (Warnung: Dies betrifft UIDocumentPickerViewController, UIImagePickerController usw.), aber Sie sollten dies wahrscheinlich nicht gemäß der Swift-Dokumentation tun :
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
open override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Wenn Sie einen Ansichts-Controller mit einem modalPresentationStyle
(zum Beispiel .overCurrentContext
) präsentieren, sollten Sie zusätzlich zur Antwort von serenn dies auch auf dem neu präsentierten Ansichts-Controller aufrufen:
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
Vergessen Sie nicht, auch den preferredStatusBarStyle
im dargestellten View Controller überschriebenen zu überschreiben .
Eine Ergänzung zu Hippos Antwort: Wenn Sie einen UINavigationController verwenden, ist es wahrscheinlich besser, eine Kategorie hinzuzufügen:
// 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
Diese Lösung ist wahrscheinlich besser als die Umstellung auf ein bald veraltetes Verhalten.
preferredStatusBarStyle
UINavigationController-spezifische Logik implementiert und ausführt. Im Moment basiert diese Logik auf, navigationBar.barStyle
aber ich kann sehen, dass zusätzliche Überprüfungen hinzugefügt werden (z. B. UISearchDisplayController
Bewegen, um den Navigationsleistenmodus auszublenden). Wenn Sie die Standardlogik überschreiben, verlieren Sie all diese Funktionen und lassen sich für nervige 'wtf'-Momente in der Zukunft offen. In meiner Antwort oben finden Sie die richtige Vorgehensweise, während das Verhalten des integrierten Navigationscontrollers weiterhin unterstützt wird.
Wie in der ausgewählten Antwort erwähnt , besteht die Hauptursache darin, Ihr Fenster-Root-View-Controller-Objekt zu überprüfen.
childForStatusBarStyle
Verwenden Sie die folgenden Erweiterungen, um alle oben genannten Szenarien zu behandeln :
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
Schlüssel in info.plist
wie es wahr standardmäßigWenn Sie einen neuen Flow modal präsentieren, wird er vom vorhandenen Flow im Statusleistenstil getrennt. Angenommen, Sie präsentieren einen NewFlowUIViewController
und fügen dann einen neuen Navigations- oder TabBar-Controller hinzu. Fügen Sie NewFlowUIViewController
dann auch eine Erweiterung von hinzu NewFlowUIViewController
, um den Statusleistenstil des weiteren Ansichts-Controllers zu verwalten.
Wenn Sie modalPresentationStyle anders als fullScreen
bei der modalen Präsentation festlegen, müssen Sie modalPresentationCapturesStatusBarAppearance
true festlegen , damit der Controller für die präsentierte Ansicht die Statussteuerung für das Erscheinungsbild erhält.
UINavigationController
ist eine Unterklasse von UIViewController
(wer wusste 🙃)!
Wenn Sie in Navigationscontrollern eingebettete Ansichtscontroller präsentieren, präsentieren Sie die eingebetteten Ansichtscontroller daher nicht wirklich. Sie präsentieren die Navigationssteuerungen! UINavigationController
, als Unterklasse von UIViewController
, erbt preferredStatusBarStyle
undchildForStatusBarStyle
, die Sie nach Wunsch einstellen können.
Jede der folgenden Methoden sollte funktionieren:
info.plist
die folgende Eigenschaft hinzu:
UIUserInterfaceStyle
(auch bekannt als "User Interface Style")preferredStatusBarStyle
Innerhalb überschreibenUINavigationController
preferredStatusBarStyle
( doc ) - Der bevorzugte Statusleistenstil für den AnsichtscontrollerUnterklasse oder erweitern UINavigationController
class MyNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
ODER
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
childForStatusBarStyle
Innerhalb überschreibenUINavigationController
childForStatusBarStyle
( doc ) - Wird aufgerufen, wenn das System den Ansichtscontroller zur Bestimmung des Statusleistenstils benötigt"Wenn Ihr Container-Ansichts-Controller seinen Statusleistenstil von einem seiner untergeordneten Ansichts-Controller ableitet, [überschreiben Sie diese Eigenschaft] und geben Sie diesen untergeordneten Ansichts-Controller zurück. Wenn Sie null zurückgeben oder diese Methode nicht überschreiben, wird der Statusleistenstil für self verwendet Wenn sich der Rückgabewert dieser Methode ändert, rufen Sie die Methode setNeedsStatusBarAppearanceUpdate () auf. "
Unterklasse oder erweitern UINavigationController
class MyNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
ODER
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
Sie können jeden View Controller zurückgeben, den Sie oben möchten. Ich empfehle eine der folgenden Möglichkeiten:
topViewController
(of UINavigationController
) ( doc ) - Der Ansichts-Controller oben im NavigationsstapelvisibleViewController
(of UINavigationController
) ( doc ) - Der Ansichtscontroller, der der aktuell sichtbaren Ansicht in der Navigationsoberfläche zugeordnet ist (Hinweis: Dies kann "einen Ansichtscontroller umfassen, der modal über dem Navigationscontroller selbst dargestellt wurde").Hinweis: Wenn Sie sich für eine Unterklasse entscheiden UINavigationController
, denken Sie daran, diese Klasse über den Identitätsinspektor in IB auf Ihre Navigationssteuerungen anzuwenden.
PS Mein Code verwendet die Swift 5.1-Syntax 😎
Die Antwort von @ serenn oben ist für den Fall von UINavigationControllers immer noch großartig. Für Swift 3 wurden jedoch die childViewController-Funktionen in geändert vars
. Der UINavigationController
Erweiterungscode sollte also lauten:
override open var childViewControllerForStatusBarStyle: UIViewController? {
return topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return topViewController
}
Und dann im Ansichts-Controller, der den Stil der Statusleiste bestimmen soll:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Wenn sich Ihr viewController unter UINavigationController befindet.
Unterklasse UINavigationController und hinzufügen
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
ViewController preferredStatusBarStyle
wird aufgerufen.
UIStatusBarStyle in iOS 7
Die Statusleiste in iOS 7 ist transparent, die Ansicht dahinter ist durchsichtig.
Der Stil der Statusleiste bezieht sich auf das Erscheinungsbild des Inhalts. In iOS 7 ist der Inhalt der Statusleiste entweder dunkel ( UIStatusBarStyleDefault
) oder hell ( UIStatusBarStyleLightContent
). Beide UIStatusBarStyleBlackTranslucent
und UIStatusBarStyleBlackOpaque
sind in iOS 7.0 veraltet. Verwenden Sie UIStatusBarStyleLightContent
stattdessen.
Wie man sich ändert UIStatusBarStyle
Wenn sich unter der Statusleiste eine Navigationsleiste befindet, wird der Stil der Statusleiste an den Stil der Navigationsleiste angepasst ( UINavigationBar.barStyle
):
Wenn der Navigationsleistenstil UIBarStyleDefault ist, lautet der Statusleistenstil UIStatusBarStyleDefault
. Wenn der Navigationsleistenstil ist UIBarStyleBlack
, ist der Statusleistenstil UIStatusBarStyleLightContent
.
Befindet sich unterhalb der Statusleiste keine Navigationsleiste, kann der Stil der Statusleiste von einem einzelnen Ansichts-Controller gesteuert und geändert werden, während die App ausgeführt wird.
- [UIViewController preferredStatusBarStyle]
ist eine neue Methode, die in iOS 7 hinzugefügt wurde. Sie kann überschrieben werden, um den bevorzugten Statusleistenstil zurückzugeben:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Wenn der Statusleistenstil von einem untergeordneten Ansichtscontroller anstelle von self gesteuert werden soll, überschreiben Sie ihn -[UIViewController childViewControllerForStatusBarStyle]
, um diesen untergeordneten Ansichtscontroller zurückzugeben.
Wenn Sie dieses Verhalten lieber deaktivieren und den Statusleistenstil mithilfe der -[UIApplication statusBarStyle]
Methode festlegen möchten , fügen Sie den UIViewControllerBasedStatusBarAppearance
Schlüssel zur Info.plist
Datei einer App hinzu und geben Sie den Wert NO ein.
Wenn jemand einen Navigationscontroller verwendet und möchte, dass alle Navigationscontroller den schwarzen Stil haben, können Sie in Swift 3 eine Erweiterung zu UINavigationController wie diese schreiben, die für alle Navigationscontroller gilt (anstatt sie einem Controller an einem zuzuweisen Zeit).
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.barStyle = UIBarStyle.black
}
}
In Swift für jede Art von UIViewController:
In Ihrem AppDelegate
Set:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootController
kann jede Art von sein UIViewController
, zB UITabBarController
oder UINavigationController
.
Überschreiben Sie dann diesen Root-Controller wie folgt:
class RootController: UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
Dadurch wird das Erscheinungsbild der Statusleiste in Ihrer gesamten App geändert, da der Root-Controller allein für das Erscheinungsbild der Statusleiste verantwortlich ist.
Denken Sie daran, die Eigenschaft View controller-based status bar appearance
in Ihrem auf YES Info.plist
zu setzen, damit dies funktioniert (dies ist die Standardeinstellung).
Die meisten Antworten enthalten keine gute Implementierung der childViewControllerForStatusBarStyle
Methode für UINavigationController
. Nach meiner Erfahrung sollten Sie solche Fälle behandeln, in denen der transparente Ansichtscontroller über dem Navigationscontroller angezeigt wird. In diesen Fällen sollten Sie die Steuerung an Ihren Modal Controller ( visibleViewController
) übergeben, jedoch nicht, wenn dieser verschwindet.
override var childViewControllerForStatusBarStyle: UIViewController? {
var childViewController = visibleViewController
if let controller = childViewController, controller.isBeingDismissed {
childViewController = topViewController
}
return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
Da für iOS 13.4 die preferredStatusBarStyle
Methode in der UINavigationController
Kategorie nicht aufgerufen wird, scheint Swizzling die einzige Option zu sein, ohne dass eine Unterklasse verwendet werden muss.
Beispiel:
Kategorie-Header:
@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end
Implementierung:
#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
Verwendung in AppDelegate.h:
#import "UINavigationController+StatusBarStyle.h"
[UINavigationController setUseLightStatusBarStyle];
Hier ist meine Methode, um dies zu lösen.
Definieren Sie ein Protokoll namens AGViewControllerAppearance .
AGViewControllerAppearance.h
#import <Foundation/Foundation.h>
@protocol AGViewControllerAppearance <NSObject>
@optional
- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;
@end
Definieren Sie in UIViewController eine Kategorie namens 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
Jetzt ist es an der Zeit zu sagen, dass Ihr View Controller das AGViewControllerAppearance- Protokoll implementiert .
Beispiel:
@interface XYSampleViewController () <AGViewControllerAppearance>
... the rest of the interface
@end
Natürlich können Sie den Rest der Verfahren (Umsetzung showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) aus dem Protokoll und UIViewController + Upgrade - tun die Anpassung richtige auf der Grundlage der von ihnen gelieferten Werte.
Beachten Sie dies bei Verwendung der self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
Lösung
Stellen Sie sicher, dass Sie zu Ihrer Liste gehen und "Erscheinungsbild der Controller-basierten Statusleiste anzeigen" auf JA setzen. Wenn es NEIN ist, wird es nicht funktionieren.
Seit Xcode 11.4 überschreiben die preferredStatusBarStyle
funktioniert das Eigenschaft in einer UINavigationController-Erweiterung nicht mehr, da sie nicht aufgerufen wird.
Das Einstellen barStyle
von navigationBar
auf .black
funktioniert zwar, dies führt jedoch zu unerwünschten Nebenwirkungen, wenn Sie der Navigationsleiste Unteransichten hinzufügen, die für den Hell- und Dunkelmodus möglicherweise unterschiedlich aussehen. Denn wenn Sie die Option barStyle
auf Schwarz setzen, wird die userInterfaceStyle
Ansicht, die in die Navigationsleiste eingebettet ist, immer userInterfaceStyle.dark
unabhängig userInterfaceStyle
von der App angezeigt .
Die richtige Lösung, die ich finde, besteht darin, eine Unterklasse von hinzuzufügen UINavigationController
und dort zu überschreiben preferredStatusBarStyle
. Wenn Sie dann diesen benutzerdefinierten UINavigationController für alle Ihre Ansichten verwenden, befinden Sie sich auf der Speicherseite.
Der NavigationController oder der TabBarController sind diejenigen, die den Stil bereitstellen müssen. Hier ist, wie ich gelöst habe: https://stackoverflow.com/a/39072526/242769