Natknąłem się teraz na kilka przypadków, w których wygodnie byłoby znaleźć „najwyższy” kontroler widoku (ten odpowiedzialny za bieżący widok), ale nie znalazłem sposobu, aby to zrobić.
Zasadniczo wyzwanie jest następujące: biorąc pod uwagę, że wykonuje się w klasie, która nie jest kontrolerem widoku (lub widokiem) [i nie ma adresu aktywnego widoku] i nie został przekazany adres najwyższego kontrolera widoku ( lub powiedzmy adres kontrolera nawigacyjnego), czy można znaleźć tego kontrolera widoku? (A jeśli tak, to w jaki sposób?)
Lub, w przeciwnym razie, czy można znaleźć najwyższy widok?
ios
objective-c
uiview
uiviewcontroller
uikit
Hot Licks
źródło
źródło
Odpowiedzi:
iOS 4 wprowadził właściwość rootViewController w UIWindow:
Musisz jednak ustawić go sam po utworzeniu kontrolera widoku.
źródło
-[UINavigationController topViewController]
). Potem jest słowo „root”, które jest korzeniem drzewa (jak-[UIWindow rootViewController]
.Myślę, że potrzebujesz kombinacji zaakceptowanej odpowiedzi i @ fishstix
Swift 3.0+
źródło
UINavigationController
i poprosić o to,topViewController
a nawet sprawdzićUITabBarController
i poprosić oselectedViewController
. W ten sposób uzyskasz kontroler widoku, który jest obecnie widoczny dla użytkownika.Aby uzupełnić odpowiedź JonasG (która pominęła kontrolery paska kart podczas przechodzenia), oto moja wersja zwracania obecnie widocznego kontrolera widoku:
źródło
childViewControllers
Kompletna wersja nierekurencyjna, dbająca o różne scenariusze:
UINavigationController
UITabBarController
Cel C
Swift 4+
źródło
visibleViewController
aby wyjaśnić, co robi.Uzyskiwanie najlepszego kontrolera widoku dla Swift przy użyciu rozszerzeń
Kod:
Stosowanie:
źródło
Aby wypełnić odpowiedź Erica (która pominęła okna popover, kontrolery nawigacyjne, kontrolery paska tabulatorów, kontrolery widoku dodane jako podviewy do niektórych innych kontrolerów widoku podczas przechodzenia), oto moja wersja zwracania obecnie widocznego kontrolera widoku:
================================================== ===================
================================================== ===================
A teraz wszystko, co musisz zrobić, aby uzyskać najwyższy kontroler widoku, to wywołaj powyższą metodę w następujący sposób:
źródło
Ta odpowiedź obejmuje
childViewControllers
i utrzymuje czystą i czytelną implementację.źródło
Niedawno dostałem tę sytuację w jednym z moich projektów, który wymagał wyświetlenia widoku powiadomienia niezależnie od wyświetlanego kontrolera i typu (UINavigationController, klasyczny kontroler lub niestandardowy kontroler widoku), gdy zmienił się status sieci.
Właśnie wydałem swój kod, który jest dość łatwy i faktycznie oparty na protokole, dzięki czemu jest elastyczny dla każdego typu kontrolera kontenera. Wydaje się, że jest to związane z ostatnimi odpowiedziami, ale w bardzo elastyczny sposób.
Możesz pobrać kod tutaj: PPTopMostController
I uzyskał najwyższą liczbę kontrolerów
źródło
To jest ulepszenie odpowiedzi Erica:
_topMostController(UIViewController *cont)
jest funkcją pomocniczą.Teraz wystarczy zadzwonić,
topMostController()
a najwyższy UIViewController powinien zostać zwrócony!źródło
self
należy.Oto moje zdanie na ten temat. Dzięki @Stakenborg za wskazanie sposobu na pominięcie uzyskania UIAlertView jako najlepszego kontrolera
źródło
getSomething:
w Objective-C. Ma to specjalne znaczenie (więcej: cocoadevcentral.com/articles/000082.php ) i nie spełniasz tych wymagań w kodzie.źródło
źródło
Najnowsza wersja Swift:
utwórz plik, nazwij go
UIWindowExtension.swift
i wklej następujący fragment:Użyj go w dowolnym miejscu jako:
źródło
switch
zamiast jeśli inaczej. 3. nie jestem pewien, czy potrzebujesz również funkcji statycznej, myślę, że możesz to zrobić z łatwością na poziomie pierwszej instancji var, który zadeklarowałeś. 4. Prawdopodobnie najlepiej nie tworzyć zbyt wielu globalnych funkcji, ale to kwestia gustu. Możesz użyć jednego wiersza kodu, aby osiągnąć efekt funkcji globalnej:UIApplication.sharedApplication().delegate?.window?.visibleViewController
Proste rozszerzenie
UIApplication
w Swift:UWAGA:
Dba o to
moreNavigationController
w środkuUITabBarController
Proste użycie:
źródło
Użyj poniższego rozszerzenia, aby złapać prąd widoczny
UIViewController
. Pracował dla Swift 4.0 i późniejszychSwift 4.0 i nowsze:
Jak używać?
źródło
presentedViewController
początku, przedUINavigationController
iUITabBarController
przypadkach? W przeciwnym razie, jeśli kontroler widoku jest modalnie prezentowany zUINavigationController
lubUITabBarController
, nie zostanie zwrócony jako kontroler widoku z góry, nawet jeśli jest to kontroler widoku, który jest widoczny.Kolejne szybkie rozwiązanie
źródło
Rozszerzenie Swift 4.2
Używaj go z dowolnego miejsca, np.
lub jak
Dopasuj do dowolnych klas, takich jak UINavigationController, UITabBarController
Cieszyć się!
źródło
Oto, co zadziałało dla mnie.
Odkryłem, że czasami kontroler był zerowy w oknie klucza, ponieważ keyWindow to coś takiego jak alert itp.
źródło
Rozwijając odpowiedź @ Erica, musisz uważać, aby keyWindow było faktycznie oknem, które chcesz. Jeśli próbujesz użyć tej metody na przykład po stuknięciu czegoś w widoku alertu, keyWindow będzie w rzeczywistości oknem alertu, co z pewnością spowoduje problemy. Zdarzyło mi się to na wolności, gdy obsługiwałem głębokie linki za pośrednictwem alertu i spowodowało SIGABRT bez BRAKU ŚLADU. Całkowita suka do debugowania.
Oto kod, którego teraz używam:
Możesz to połączyć z dowolnym smakiem pobierania kontrolera widoku z góry, który lubisz z innych odpowiedzi na to pytanie.
źródło
Alternatywne rozwiązanie Swift:
źródło
To rozwiązanie jest najbardziej kompletne. Uwzględnia: UINavigationController UIPageViewController UITabBarController I najwyżej przedstawiony kontroler widoku z kontrolera widoku z góry
Przykład znajduje się w Swift 3.
Istnieją 3 przeciążenia
źródło
Zwięzłe, ale kompleksowe rozwiązanie w Swift 4.2, bierze pod uwagę UINavigationControllers , UITabBarControllers , kontrolery prezentowane i potomne :
Stosowanie:
źródło
Świetne rozwiązanie w Swift, wdrożenie w AppDelegate
źródło
Myślę, że większość odpowiedzi została całkowicie zignorowana
UINavigationViewController
, więc poradziłem sobie z tym przypadkiem użycia z następującą implementacją.źródło
Wiem, że jest bardzo późno i może być zbędne. Ale poniższy fragment, który wymyśliłem, działa dla mnie:
źródło
Działa to doskonale w celu znalezienia kontrolera widoku z góry 1 z dowolnego elementu sterującego widokiem katalogu głównego
źródło
Nie jestem pewien, czy to pomoże w osiągnięciu tego, co próbujesz osiągnąć, znajdując najwyższy kontroler widoku, ale próbowałem przedstawić nowy kontroler widoku, ale jeśli mój główny kontroler widoku miał już modalne okno dialogowe, zostanie ono zablokowane, więc ja przejdzie na górę wszystkich kontrolerów widoku modalnego, używając tego kodu:
źródło
możesz znaleźć najwyżej kontroler widoku, używając
źródło
self
nie ma żadnejnavigationController
właściwości.Inne rozwiązanie opiera się na łańcuchu respondentów, który może, ale nie musi działać, w zależności od tego, kto jest pierwszym responderem:
Przykład pseudo kodu:
źródło
Szybki:
Stosowanie:
źródło