Ś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).
ios
ios7
uikit
uistatusbar
trgoofi
źródło
źródło
Odpowiedzi:
Możliwa przyczyna pierwotna
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łempreferredStatusBarStyle
był używany wUITabBarController
, 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 (ipreferredStatusBarStyle
wywołano metodę).Metoda alternatywna (przestarzałe w iOS 9)
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
:lub
Pamiętaj, że musisz również ustawić
UIViewControllerBasedStatusBarAppearance
naNO
plik plist, jeśli używasz tej metody.źródło
setNeedsStatusBarAppearanceUpdate
- moje podejrzenia zostały potwierdzone, kiedy dokonałem tej zmiany.Dla wszystkich korzystających z UINavigationController:
UINavigationController
Nie do przodu napreferredStatusBarStyle
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 implementacjapreferredStatusBarStyle
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
lubUIStatusBarStyleLightContent
. Opiera to na swoimUINavigationBar.barStyle
. Ustawienie domyślne (UIBarStyleDefault
) powoduje wyświetlenie ciemnegoUIStatusBarStyleDefault
paska stanu pierwszego planu . IUIBarStyleBlack
daUIStatusBarStyleLightContent
pasek stanu.TL; DR:
Jeśli chcesz
UIStatusBarStyleLightContent
wUINavigationController
użyciu:źródło
preferredStatusBarStyle
w rzeczywistości zostanie wywołany na kontrolerze widoku potomnego, jeśli ukryjesz pasek nawigacji (ustawionynavigationBarHidden
naYES
), dokładnie tak, jak to właściwe.[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
zestaw doYES
rzeczywiściepreferredStatusBarStyle
zadzwonił, oraz ostrzeżenie dla tych, którzy mogą się na to natknąć: działa znavigationBarHidden
, ale nie znavigationBar.hidden
!Więc faktycznie dodałem kategorię do UINavigationController, ale użyłem metod:
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:
W celu C:
I na dokładkę, oto jak jest to zaimplementowane następnie w UIViewController:
W Swift
W celu C
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?)
źródło
return self.topViewController;
działa dla mnie, alereturn self.visibleViewController;
- niesuper
tej metody i naprawdę chcesz zmienić zachowanie wszystkich kontrolerów tego typuDla każdego, kto wciąż zmaga się z tym, to proste rozszerzenie w trybie szybkim powinno rozwiązać problem.
źródło
Moja aplikacja stosować wszystkie trzy:
UINavigationController
,UISplitViewController
,UITabBarController
, a więc wszystkie one wydają się przejąć kontrolę nad pasku stanu i spowodujepreferedStatusBarStyle
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.Edycja: aktualizacja zmian interfejsu API Swift 4.2
źródło
Odpowiedź Tysona jest poprawna w przypadku zmiany koloru paska stanu na biały
UINavigationController
.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ć.Kod
źródło
Na UINavigationController
preferredStatusBarStyle
nie jest wywoływany, ponieważtopViewController
jest preferowanyself
. Aby więc zostaćpreferredStatusBarStyle
wywołanym na UINavigationController, musisz go zmienićchildViewControllerForStatusBarStyle
.Rekomendacje
Zastąp swój UINavigationController w swojej klasie:
Niezalecana alternatywa
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 :
źródło
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:Nie zapomnij również zastąpić
preferredStatusBarStyle
przedstawionego kontrolera widoku.źródło
Dodatek do odpowiedzi Hippo: jeśli używasz UINavigationController, prawdopodobnie lepiej jest dodać kategorię:
To rozwiązanie jest prawdopodobnie lepsze niż przejście na przestarzałe zachowanie.
źródło
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.Swift 4.2 i wyżej
Jak wspomniano w wybranej odpowiedzi , główną przyczyną jest sprawdzenie obiektu kontrolera widoku głównego okna.
Możliwe przypadki twojej struktury przepływu
Twój kontroler widoku głównego okna jest obiektem UIViewController i dodatkowo dodaje lub usuwa kontroler nawigacji lub tabController w oparciu o przepływ aplikacji.
Ten rodzaj przepływu jest zwykle używany, jeśli aplikacja ma przepływ przed logowaniem na stosie nawigacji bez kart i przepływ po logowaniu za pomocą kart, a być może każda karta zawiera ponadto kontroler nawigacji.
Jest to przepływ, w którym kontrolerem widoku głównego okna jest tabBarController, prawdopodobnie każda karta zawiera ponadto kontroler nawigacji.
Jest to przepływ, w którym kontrolerem widoku głównego okna jest NavigationController.
Nie jestem pewien, czy istnieje możliwość dodania kontrolera paska kart lub nowego kontrolera nawigacyjnego do istniejącego kontrolera nawigacyjnego. Ale jeśli jest taki przypadek, musimy przekazać kontrolę stylu paska stanu do następnego kontenera. Dodałem więc to samo sprawdzenie w rozszerzeniu UINavigationController, aby znaleźć
childForStatusBarStyle
Użyj następujących rozszerzeń, obsługuje wszystkie powyższe scenariusze -
UIViewControllerBasedStatusBarAppearance
klucza,info.plist
ponieważ domyślnie jest to prawdaPunkty do rozważenia w przypadku bardziej złożonych przepływów
W 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 doNewFlowUIViewController
, 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.źródło
Rozwiązania iOS 13
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 podklasaUIViewController
dziedziczypreferredStatusBarStyle
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
LUB
Zastąp
childForStatusBarStyle
w ciąguUINavigationController
childForStatusBarStyle
( dok ) - Wywoływany, gdy system potrzebuje kontrolera widoku do określania stylu paska stanuPodklasa lub rozszerzenie
UINavigationController
LUB
Możesz zwrócić dowolny kontroler widoku, który chcesz powyżej. Polecam jedno z poniższych:
topViewController
(zUINavigationController
) ( dok ) - Kontroler widoku u góry stosu nawigacjivisibleViewController
(ofUINavigationController
) ( 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 😎
źródło
Powyższa odpowiedź @ serenn jest nadal świetna w przypadku UINavigationControllers. Jednak w swift 3 funkcje childViewController zostały zmienione na
vars
. ZatemUINavigationController
kod rozszerzenia powinien być:A następnie w kontrolerze widoku, który powinien dyktować styl paska stanu:
źródło
Jeśli Twój viewController znajduje się w obszarze UINavigationController.
Podklasa UINavigationController i dodaj
ViewController
preferredStatusBarStyle
zostanie wywołany.źródło
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ównoUIStatusBarStyleBlackTranslucent
iUIStatusBarStyleBlackOpaque
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 jestUIBarStyleBlack
, 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: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, dodajUIViewControllerBasedStatusBarAppearance
klucz do pliku aplikacjiInfo.plist
i nadaj mu wartość NIE.źródło
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).
źródło
W Swift dla dowolnego rodzaju UIViewController:
W twoim
AppDelegate
zestawie:myRootController
może być dowolnego rodzajuUIViewController
, np .UITabBarController
lubUINavigationController
.Następnie zastąp ten kontroler root w następujący sposób:
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).źródło
Rozwiązanie Swift 3 iOS 10:
źródło
Większość odpowiedzi nie obejmuje dobrej implementacji
childViewControllerForStatusBarStyle
metody dlaUINavigationController
. 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.źródło
W moim przypadku przypadkowo przedstawiłem View / Navigation Controller as
UIModalPresentationStyle.overFullScreen
, co powoduje, żepreferredStatusBarStyle
nie jestem wywoływany. Po przełączeniu z powrotemUIModalPresentationStyle.fullScreen
wszystko działa.źródło
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:
Realizacja:
Zastosowanie w AppDelegate.h:
źródło
Oto moja metoda rozwiązania tego problemu.
Zdefiniuj protokół o nazwie AGViewControllerAppearance .
AGViewControllerAppearance.h
Zdefiniuj kategorię w UIViewController o nazwie Upgrade .
UIViewController + Upgrade.h
UIViewController + Upgrade.m
Czas powiedzieć, że kontroler widoku implementuje wygląd AGViewController protokół .
Przykład:
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.
źródło
Jeśli ktoś napotka ten problem z UISearchController. Po prostu utwórz nową podklasę UISearchController, a następnie dodaj kod poniżej do tej klasy:
źródło
Pamiętaj, że podczas korzystania z
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
rozwiązaniakoniecznie przejdź do swojej listy i ustaw „Wyświetl wygląd paska stanu kontrolera” na TAK. Jeśli NIE, to nie będzie działać.
źródło
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
znavigationBar
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 nabarStyle
czarny spowoduje, żeuserInterfaceStyle
widok osadzony w pasku nawigacji będzie zawsze miałuserInterfaceStyle.dark
niezależnie oduserInterfaceStyle
aplikacji.Właściwym rozwiązaniem, które wymyślam, jest dodanie podklasy
UINavigationController
i zastąpienie gopreferredStatusBarStyle
. Jeśli następnie użyjesz tego niestandardowego kontrolera UINavigationController dla wszystkich swoich widoków, będziesz po stronie zapisywania.źródło
NavigationController lub TabBarController to te, które muszą podać styl. Oto jak rozwiązałem: https://stackoverflow.com/a/39072526/242769
źródło