Ich bin jetzt auf einige Fälle gestoßen, in denen es praktisch wäre, den "obersten" Ansichts-Controller (den für die aktuelle Ansicht verantwortlichen) zu finden, aber keinen Weg gefunden, dies zu tun.
Grundsätzlich ist die Herausforderung folgende: Vorausgesetzt, man führt in einer Klasse aus, die kein View Controller (oder eine View) ist. [und nicht die Adresse einer aktiven Ansicht hat] und der die Adresse des obersten Ansichtscontrollers nicht übergeben wurde ( oder beispielsweise die Adresse des Navigationscontrollers), ist es möglich, diesen Ansichtscontroller zu finden? (Und wenn ja, wie?)
Oder ist es sonst möglich, die oberste Ansicht zu finden?
ios
objective-c
uiview
uiviewcontroller
uikit
Hot Licks
quelle
quelle
Antworten:
iOS 4 hat die rootViewController-Eigenschaft in UIWindow eingeführt:
Sie müssen es jedoch selbst einstellen, nachdem Sie den Ansichts-Controller erstellt haben.
quelle
-[UINavigationController topViewController]
). Dann gibt es das Wort „Wurzel“, das die Wurzel des Baumes ist (wie-[UIWindow rootViewController]
.Ich denke, Sie brauchen eine Kombination aus der akzeptierten Antwort und @ fishstix
Swift 3.0+
quelle
UINavigationController
und danach fragentopViewController
oder sogar nachsehenUITabBarController
und fragenselectedViewController
. Dadurch erhalten Sie den View Controller, der derzeit für den Benutzer sichtbar ist.Um die Antwort von JonasG zu vervollständigen (der beim Durchlaufen die Registerkarten-Controller ausgelassen hat), ist hier meine Version der Rückgabe des aktuell sichtbaren Ansichts-Controllers:
quelle
childViewControllers
Eine vollständige nicht rekursive Version, die verschiedene Szenarien berücksichtigt:
UINavigationController
UITabBarController
Ziel c
Swift 4+
quelle
visibleViewController
, um klar zu machen, was es tut.Erhalten des Top View View Controllers für Swift mithilfe von Erweiterungen
Code:
Verwendung:
quelle
Um Erics Antwort zu vervollständigen (der Popover, Navigations-Controller, Tabbar-Controller, Ansichts-Controller, die während des Durchlaufs als Unteransichten zu einigen anderen Ansichts-Controllern hinzugefügt wurden, weggelassen hat), ist hier meine Version der Rückgabe des aktuell sichtbaren Ansichts-Controllers:
================================================== ===================
================================================== ===================
Und jetzt müssen Sie nur noch die obige Methode wie folgt aufrufen, um den Top View Controller zu erhalten:
quelle
Diese Antwort beinhaltet
childViewControllers
und pflegt eine saubere und lesbare Implementierung.quelle
Ich habe diese Situation kürzlich in einem meiner Projekte erhalten, in dem eine Benachrichtigungsansicht angezeigt werden musste, unabhängig davon, welcher Controller angezeigt wurde und welcher Typ (UINavigationController, klassischer Controller oder benutzerdefinierter Ansichtscontroller), wenn sich der Netzwerkstatus änderte.
Also habe ich meinen Code veröffentlicht, der recht einfach ist und tatsächlich auf einem Protokoll basiert, so dass er für jede Art von Container-Controller flexibel ist. Es scheint mit den letzten Antworten verbunden zu sein, aber auf sehr flexible Weise.
Sie können den Code hier herunterladen: abrufen PPTopMostController
Und bekam den Top-Controller mit
quelle
Dies ist eine Verbesserung von Erics Antwort:
_topMostController(UIViewController *cont)
ist eine Hilfsfunktion.Jetzt müssen Sie nur noch anrufen
topMostController()
und der oberste UIViewController sollte zurückgegeben werden!quelle
self
gehören soll.Hier ist meine Meinung dazu. Vielen Dank an @Stakenborg für den Hinweis, wie Sie es überspringen können, UIAlertView als obersten Controller zu erhalten
quelle
getSomething:
in Objective-C vermeiden . Dies hat eine besondere Bedeutung (mehr: cocoadevcentral.com/articles/000082.php ) und Sie erfüllen diese Anforderungen in Ihrem Code nicht.quelle
quelle
Für die neueste Swift-Version:
Erstellen Sie eine Datei, benennen Sie sie
UIWindowExtension.swift
und fügen Sie das folgende Snippet ein:Verwenden Sie es überall als:
quelle
switch
anstelle von if else. 3. Sie sind sich nicht sicher, ob Sie auch eine statische Funktion benötigen. Ich denke, Sie können dies problemlos in der von Ihnen deklarierten Variablen der ersten Instanz tun. 4. Wahrscheinlich am besten, nicht zu viele globale Funktionen zu erstellen, aber das ist Geschmackssache. Sie können eine Codezeile verwenden, um den Effekt der globalen Funktion zu erzielen:UIApplication.sharedApplication().delegate?.window?.visibleViewController
Einfache Erweiterung für
UIApplication
in Swift:HINWEIS:
Es kümmert sich um
moreNavigationController
innenUITabBarController
Einfache Verwendung:
quelle
Verwenden Sie die folgende Erweiterung, um den sichtbaren Strom zu erfassen
UIViewController
. Arbeitete für Swift 4.0 und höherSwift 4.0 und höher:
Wie benutzt man?
quelle
presentedViewController
zuerst vor denUINavigationController
undUITabBarController
Fällen erfolgen? Andernfalls wird ein Ansichts-Controller, der modal von einemUINavigationController
oder dargestelltUITabBarController
wird, nicht als Draufsicht-Controller zurückgegeben, obwohl der Ansichts-Controller sichtbar ist.Noch eine schnelle Lösung
quelle
Swift 4.2-Erweiterung
Verwenden Sie es von überall wie,
oder wie,
Passt zu allen Klassen wie UINavigationController, UITabBarController
Genießen!
quelle
Hier ist, was für mich funktioniert hat.
Ich stellte fest, dass der Controller manchmal im Schlüsselfenster Null war, da das keyWindow ein Betriebssystem wie eine Warnung usw. ist.
quelle
Wenn Sie die Antwort von @ Eric erweitern, müssen Sie darauf achten, dass das keyWindow tatsächlich das gewünschte Fenster ist. Wenn Sie versuchen, diese Methode zu verwenden, nachdem Sie beispielsweise in einer Warnungsansicht auf etwas getippt haben, ist das keyWindow tatsächlich das Fenster der Warnung, und dies führt zweifellos zu Problemen für Sie. Dies passierte mir in freier Wildbahn beim Umgang mit Deep Links über einen Alarm und verursachte SIGABRTs ohne NO STACK TRACE. Total Hündin zum Debuggen.
Hier ist der Code, den ich jetzt verwende:
Fühlen Sie sich frei, dies mit einer beliebigen Art des Abrufens des von Ihnen gewünschten Draufsicht-Controllers aus den anderen Antworten auf diese Frage zu mischen.
quelle
Alternative Swift-Lösung:
quelle
Diese Lösung ist die vollständigste. Es berücksichtigt: UINavigationController UIPageViewController UITabBarController Und den am häufigsten präsentierten View Controller vom Top View Controller
Das Beispiel ist in Swift 3.
Es gibt 3 Überladungen
quelle
Eine kurze , aber umfassende Lösung in Swift 4.2, berücksichtigt UINavigationControllers , UITabBarControllers , präsentiert und Kind View - Controller:
Verwendung:
quelle
Tolle Lösung in Swift, in AppDelegate implementieren
quelle
Ich denke, die meisten Antworten wurden vollständig ignoriert
UINavigationViewController
, daher habe ich diesen Anwendungsfall mit der folgenden Implementierung behandelt.quelle
Ich weiß, dass es sehr spät ist und möglicherweise überflüssig ist. Aber das Folgende ist der Ausschnitt, den ich mir ausgedacht habe und der für mich funktioniert:
quelle
Dies funktioniert hervorragend, um den Top ViewController 1 aus einer beliebigen Stammansicht zu finden
quelle
Ich bin mir nicht sicher, ob dies helfen wird, was Sie erreichen möchten, indem Sie den obersten Ansichts-Controller finden, aber ich habe versucht, einen neuen Ansichts-Controller zu präsentieren. Wenn mein Root-Ansichts-Controller jedoch bereits einen modalen Dialog hatte, würde dieser blockiert, also ich würde mit diesem Code an die Spitze aller Modal View Controller fahren:
quelle
Sie können den obersten Ansichts-Controller mithilfe von finden
quelle
self
keinenavigationController
Eigenschaft hat.Eine andere Lösung basiert auf der Responderkette, die je nach Ersthelfer möglicherweise funktioniert oder nicht:
Beispiel Pseudocode:
quelle
Schnell:
Verwendung:
quelle