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.)
ios
ios7
uikit
uistatusbar
trgoofi
quelle
quelle
Antworten:
Mögliche Grundursache
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 verwendetUITabBarController
, 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 diepreferredStatusBarStyle
Methode wurde aufgerufen).Alternative Methode (veraltet in iOS 9)
Alternativ können Sie in jedem Ihrer Ansichts-Controller je nach Hintergrundfarbe eine der folgenden Methoden aufrufen, anstatt sie verwenden zu müssen
setNeedsStatusBarAppearanceUpdate
:oder
Beachten Sie, dass Sie auch Set benötigen ,
UIViewControllerBasedStatusBarAppearance
umNO
in der plist - Datei , wenn Sie diese Methode verwenden.quelle
setNeedsStatusBarAppearanceUpdate
- mein Verdacht wurde bestätigt, als ich diese Änderung vornahm.Für alle, die einen UINavigationController verwenden:
Der
UINavigationController
leitet keinepreferredStatusBarStyle
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 ImplementierungpreferredStatusBarStyle
in Ihren VCs innerhalb eines Navigationscontrollers nichts bewirken - sie werden niemals aufgerufen.Der Trick ist, was die
UINavigationController
verwendet, um zu entscheiden, was fürUIStatusBarStyleDefault
oder zurückgegeben werden sollUIStatusBarStyleLightContent
. Es stützt dies auf seineUINavigationBar.barStyle
. Das default (UIBarStyleDefault
) führt zur dunklen VordergrundstatusleisteUIStatusBarStyleDefault
. UndUIBarStyleBlack
gibt eineUIStatusBarStyleLightContent
Statusleiste.TL; DR:
Wenn Sie
UIStatusBarStyleLightContent
eineUINavigationController
Verwendung wünschen :quelle
preferredStatusBarStyle
tatsächlich auf dem untergeordneten Ansichtscontroller aufgerufen wird, wenn Sie die Navigationsleiste (navigationBarHidden
aufYES
) genau entsprechend ausblenden .[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
set toYES
tatsächlichpreferredStatusBarStyle
angerufen hat, und eine Warnung an diejenigen, die darüber stolpern könnten: Es funktioniert mitnavigationBarHidden
, aber nicht mitnavigationBar.hidden
!Also habe ich UINavigationController tatsächlich eine Kategorie hinzugefügt, aber die folgenden Methoden verwendet:
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:
In Ziel-C:
Und hier ist, wie es dann in einem UIViewController implementiert wird:
In Swift
In Ziel-C
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?)
quelle
return self.topViewController;
funktioniert für mich, aberreturn self.visibleViewController;
- nichtsuper
in dieser Methode , und Sie wollen tatsächlich das Verhalten aller Controller dieser Art zu ändernFür alle, die immer noch damit zu kämpfen haben, sollte diese einfache Erweiterung in Swift das Problem für Sie beheben.
quelle
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.Bearbeiten: Update für Swift 4.2 API-Änderungen
quelle
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 dieAppDelegate's
didFinishLaunchingWithOptions
Methode.Und vergessen Sie nicht , die zu setzen ,
UIViewControllerBasedStatusBarAppearance
umYES
in der .plist - Datei, sonst wird die Änderung nicht widerspiegeln.Code
quelle
Wird auf einem UINavigationController
preferredStatusBarStyle
nicht aufgerufen, da diestopViewController
bevorzugt wirdself
. UmpreferredStatusBarStyle
auf einem UINavigationController aufgerufen zu werden, müssen Sie dessen ändernchildViewControllerForStatusBarStyle
.Empfehlung
Überschreiben Sie Ihren UINavigationController in Ihrer Klasse:
Nicht empfohlene Alternative
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 :
quelle
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:Vergessen Sie nicht, auch den
preferredStatusBarStyle
im dargestellten View Controller überschriebenen zu überschreiben .quelle
Eine Ergänzung zu Hippos Antwort: Wenn Sie einen UINavigationController verwenden, ist es wahrscheinlich besser, eine Kategorie hinzuzufügen:
Diese Lösung ist wahrscheinlich besser als die Umstellung auf ein bald veraltetes Verhalten.
quelle
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.Swift 4.2 und höher
Wie in der ausgewählten Antwort erwähnt , besteht die Hauptursache darin, Ihr Fenster-Root-View-Controller-Objekt zu überprüfen.
Mögliche Fälle Ihrer Flussstruktur
Ihr Fensterstamm-Ansichts-Controller ist ein UIViewController-Objekt und fügt basierend auf Ihrem Anwendungsfluss einen Navigations-Controller oder tabController hinzu oder entfernt ihn.
Diese Art von Fluss wird normalerweise verwendet, wenn Ihre App einen Voranmeldefluss auf dem Navigationsstapel ohne Registerkarten und einen Nachanmeldefluss mit Registerkarten hat und möglicherweise jede Registerkarte weiterhin einen Navigationscontroller enthält.
Dies ist der Ablauf, in dem Window Root View Controller TabBarController ist. Möglicherweise enthält jede Registerkarte den Navigationscontroller.
Dies ist der Ablauf, in dem der Fensterstammansicht-Controller der Navigationscontroller ist.
Ich bin nicht sicher, ob es eine Möglichkeit gibt, einen Registerkartenleisten-Controller oder einen neuen Navigations-Controller in einen vorhandenen Navigations-Controller einzufügen. In diesem Fall müssen wir jedoch das Steuerelement für den Statusleistenstil an den nächsten Container übergeben. Also habe ich die gleiche Prüfung in der UINavigationController-Erweiterung hinzugefügt, um sie zu finden
childForStatusBarStyle
Verwenden Sie die folgenden Erweiterungen, um alle oben genannten Szenarien zu behandeln :
UIViewControllerBasedStatusBarAppearance
Schlüssel ininfo.plist
wie es wahr standardmäßigZu berücksichtigende Punkte für komplexere Abläufe
Wenn 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 SieNewFlowUIViewController
dann auch eine Erweiterung von hinzuNewFlowUIViewController
, um den Statusleistenstil des weiteren Ansichts-Controllers zu verwalten.Wenn Sie modalPresentationStyle anders als
fullScreen
bei der modalen Präsentation festlegen, müssen SiemodalPresentationCapturesStatusBarAppearance
true festlegen , damit der Controller für die präsentierte Ansicht die Statussteuerung für das Erscheinungsbild erhält.quelle
iOS 13 Lösung (en)
UINavigationController
ist eine Unterklasse vonUIViewController
(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 vonUIViewController
, erbtpreferredStatusBarStyle
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
ODER
childForStatusBarStyle
Innerhalb überschreibenUINavigationController
childForStatusBarStyle
( doc ) - Wird aufgerufen, wenn das System den Ansichtscontroller zur Bestimmung des Statusleistenstils benötigtUnterklasse oder erweitern
UINavigationController
ODER
Sie können jeden View Controller zurückgeben, den Sie oben möchten. Ich empfehle eine der folgenden Möglichkeiten:
topViewController
(ofUINavigationController
) ( doc ) - Der Ansichts-Controller oben im NavigationsstapelvisibleViewController
(ofUINavigationController
) ( 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 😎
quelle
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
. DerUINavigationController
Erweiterungscode sollte also lauten:Und dann im Ansichts-Controller, der den Stil der Statusleiste bestimmen soll:
quelle
Wenn sich Ihr viewController unter UINavigationController befindet.
Unterklasse UINavigationController und hinzufügen
ViewController
preferredStatusBarStyle
wird aufgerufen.quelle
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
). BeideUIStatusBarStyleBlackTranslucent
undUIStatusBarStyleBlackOpaque
sind in iOS 7.0 veraltet. Verwenden SieUIStatusBarStyleLightContent
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 istUIBarStyleBlack
, ist der StatusleistenstilUIStatusBarStyleLightContent
.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: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 denUIViewControllerBasedStatusBarAppearance
Schlüssel zurInfo.plist
Datei einer App hinzu und geben Sie den Wert NO ein.quelle
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).
quelle
In Swift für jede Art von UIViewController:
In Ihrem
AppDelegate
Set:myRootController
kann jede Art von seinUIViewController
, zBUITabBarController
oderUINavigationController
.Überschreiben Sie dann diesen Root-Controller wie folgt:
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 YESInfo.plist
zu setzen, damit dies funktioniert (dies ist die Standardeinstellung).quelle
Swift 3 iOS 10 Lösung:
quelle
Die meisten Antworten enthalten keine gute Implementierung der
childViewControllerForStatusBarStyle
Methode fürUINavigationController
. 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.quelle
In meinem Fall habe ich versehentlich den View / Navigation Controller als dargestellt
UIModalPresentationStyle.overFullScreen
, was dazu führt, dasspreferredStatusBarStyle
nicht aufgerufen wird. Nach dem ZurückschaltenUIModalPresentationStyle.fullScreen
funktioniert alles.quelle
Da für iOS 13.4 die
preferredStatusBarStyle
Methode in derUINavigationController
Kategorie nicht aufgerufen wird, scheint Swizzling die einzige Option zu sein, ohne dass eine Unterklasse verwendet werden muss.Beispiel:
Kategorie-Header:
Implementierung:
Verwendung in AppDelegate.h:
quelle
Hier ist meine Methode, um dies zu lösen.
Definieren Sie ein Protokoll namens AGViewControllerAppearance .
AGViewControllerAppearance.h
Definieren Sie in UIViewController eine Kategorie namens Upgrade .
UIViewController + Upgrade.h
UIViewController + Upgrade.m
Jetzt ist es an der Zeit zu sagen, dass Ihr View Controller das AGViewControllerAppearance- Protokoll implementiert .
Beispiel:
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.
quelle
Wenn jemand auf dieses Problem mit UISearchController stößt. Erstellen Sie einfach eine neue Unterklasse von UISearchController und fügen Sie der folgenden Klasse Code hinzu:
quelle
Beachten Sie dies bei Verwendung der
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
LösungStellen 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.
quelle
Seit Xcode 11.4 überschreiben die
preferredStatusBarStyle
funktioniert das Eigenschaft in einer UINavigationController-Erweiterung nicht mehr, da sie nicht aufgerufen wird.Das Einstellen
barStyle
vonnavigationBar
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 OptionbarStyle
auf Schwarz setzen, wird dieuserInterfaceStyle
Ansicht, die in die Navigationsleiste eingebettet ist, immeruserInterfaceStyle.dark
unabhängiguserInterfaceStyle
von der App angezeigt .Die richtige Lösung, die ich finde, besteht darin, eine Unterklasse von hinzuzufügen
UINavigationController
und dort zu überschreibenpreferredStatusBarStyle
. Wenn Sie dann diesen benutzerdefinierten UINavigationController für alle Ihre Ansichten verwenden, befinden Sie sich auf der Speicherseite.quelle
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
quelle