J'ai rencontré quelques cas où il serait pratique de pouvoir trouver le contrôleur de vue "le plus haut" (celui responsable de la vue actuelle), mais je n'ai pas trouvé de moyen de le faire.
Fondamentalement, le défi est le suivant: étant donné que l'on exécute dans une classe qui n'est pas un contrôleur de vue (ou une vue) [et qui n'a pas l'adresse d'une vue active] et qui n'a pas reçu l'adresse du contrôleur de vue le plus haut ( ou, par exemple, l'adresse du contrôleur de navigation), est-il possible de trouver ce contrôleur de vue? (Et si oui, comment?)
Ou, à défaut, est-il possible de trouver la vue la plus haute?
ios
objective-c
uiview
uiviewcontroller
uikit
Hot Licks
la source
la source
Réponses:
iOS 4 a introduit la propriété rootViewController sur UIWindow:
Vous devrez cependant le configurer vous-même après avoir créé le contrôleur de vue.
la source
-[UINavigationController topViewController]
). Ensuite, il y a le mot «racine», qui est la racine de l'arbre (comme-[UIWindow rootViewController]
.Je pense que vous avez besoin d'une combinaison de la réponse acceptée et de @ fishstix
Swift 3.0+
la source
UINavigationController
et demander sontopViewController
ou même vérifierUITabBarController
et demanderselectedViewController
. Cela vous donnera le contrôleur de vue actuellement visible par l'utilisateur.Pour compléter la réponse de JonasG (qui a omis les contrôleurs de la barre d'onglets pendant la traversée), voici ma version de retour du contrôleur de vue actuellement visible:
la source
childViewControllers
Une version complète non récursive, prenant en charge différents scénarios:
UINavigationController
UITabBarController
Objectif c
Swift 4+
la source
visibleViewController
pour que ce soit clair.Obtenir le meilleur contrôleur de vue pour Swift à l'aide d'extensions
Code:
Usage:
la source
Pour compléter la réponse d'Eric (qui a omis les popovers, les contrôleurs de navigation, les tabbarcontrollers, les contrôleurs de vue ajoutés en tant que sous-vues à d'autres contrôleurs de vue pendant la traversée), voici ma version de retour du contrôleur de vue actuellement visible:
================================================== ===================
================================================== ===================
Et maintenant, tout ce que vous devez faire pour obtenir le meilleur contrôleur de vue est d'appeler la méthode ci-dessus comme suit:
la source
Cette réponse inclut
childViewControllers
et maintient une implémentation propre et lisible.la source
J'ai récemment rencontré cette situation dans un de mes projets, qui exigeait d'afficher une vue de notification quel que soit le contrôleur affiché et quel que soit le type (UINavigationController, contrôleur classique ou contrôleur de vue personnalisé), lorsque l'état du réseau changeait.
Je viens donc de publier mon code, qui est assez simple et basé sur un protocole afin qu'il soit flexible avec chaque type de contrôleur de conteneur. Il semble être lié aux dernières réponses, mais de manière beaucoup plus flexible.
Vous pouvez récupérer le code ici: PPTopMostController
Et j'ai obtenu le meilleur contrôleur en utilisant
la source
Ceci est une amélioration de la réponse d'Eric:
_topMostController(UIViewController *cont)
est une fonction d'aide.Maintenant, tout ce que vous avez à faire est d'appeler
topMostController()
et le plus haut UIViewController devrait être retourné!la source
self
doit appartenir.Voici mon point de vue à ce sujet. Merci à @Stakenborg d'avoir indiqué la façon d'éviter d'opter pour UIAlertView comme le plus grand contrôleur
la source
getSomething:
dans Objective-C. Cela a une signification particulière (plus: cocoadevcentral.com/articles/000082.php ) et vous ne remplissez pas ces exigences dans votre code.la source
la source
Pour la dernière version de Swift:
créez un fichier, nommez-le
UIWindowExtension.swift
et collez l'extrait de code suivant:Utilisez-le n'importe où comme:
la source
switch
place de if else. 3. Je ne suis pas sûr que vous ayez également besoin d'une fonction statique, je pense que vous pourriez le faire facilement dans le premier niveau var que vous avez déclaré. 4. Il vaut probablement mieux ne pas créer trop de fonctions globales mais c'est une question de goût. Vous pouvez utiliser une ligne de code pour obtenir l'effet de la fonction globale:UIApplication.sharedApplication().delegate?.window?.visibleViewController
Extension simple pour
UIApplication
dans Swift:REMARQUE:
Ça tient à l'
moreNavigationController
intérieurUITabBarController
Utilisation simple:
la source
Utilisez l'extension ci-dessous pour saisir le courant visible
UIViewController
. A travaillé pour Swift 4.0 et versions ultérieuresSwift 4.0 et versions ultérieures:
Comment utiliser?
la source
presentedViewController
abord, avant les casUINavigationController
etUITabBarController
? Sinon, si un contrôleur de vue est présenté de manière modale à partir d'unUINavigationController
ouUITabBarController
, il ne sera pas renvoyé en tant que contrôleur de vue de dessus, même si c'est le contrôleur de vue qui est visible.Encore une autre solution Swift
la source
Extension Swift 4.2
Utilisez-le de n'importe où comme,
ou comme,
Convient à toutes les classes comme UINavigationController, UITabBarController
Prendre plaisir!
la source
Voici ce qui a fonctionné pour moi.
J'ai trouvé que parfois le contrôleur était nul sur la fenêtre de clé, car le keyWindow est quelque chose d'OS comme une alerte, etc.
la source
En développant la réponse de @ Eric, vous devez faire attention à ce que keyWindow soit en fait la fenêtre que vous souhaitez. Si vous essayez d'utiliser cette méthode après avoir tapé quelque chose dans une vue d'alerte par exemple, le keyWindow sera en fait la fenêtre de l'alerte, et cela vous causera sans aucun doute des problèmes. Cela m'est arrivé à l'état sauvage lors de la gestion des liens profonds via une alerte et a provoqué des SIGABRT avec NO STACK TRACE. Salope totale à déboguer.
Voici le code que j'utilise maintenant:
N'hésitez pas à mélanger cela avec n'importe quelle saveur de récupération du contrôleur de vue de dessus que vous aimez dans les autres réponses à cette question.
la source
Solution alternative rapide:
la source
Cette solution est la plus complète. Il prend en considération: UINavigationController UIPageViewController UITabBarController Et le contrôleur de vue présenté le plus haut du contrôleur de vue de dessus
L'exemple est dans Swift 3.
Il y a 3 surcharges
la source
Une solution concise mais complète dans Swift 4.2, prend en compte les contrôleurs UINavigationControllers , UITabBarControllers , présentés et enfants :
Usage:
la source
Grande solution dans Swift, implémenter dans AppDelegate
la source
Je pense que la plupart des réponses ont complètement ignoré
UINavigationViewController
, j'ai donc géré ce cas d'utilisation avec l'implémentation suivante.la source
Je sais que c'est très tard et peut être redondant. Mais voici l'extrait de code que j'ai trouvé et qui fonctionne pour moi:
la source
Cela fonctionne très bien pour trouver le viewController 1 supérieur à partir de n'importe quel contrôle de vue racine
la source
Je ne sais pas si cela aidera ce que vous essayez d'accomplir en trouvant le contrôleur de vue le plus haut, mais j'essayais de présenter un nouveau contrôleur de vue, mais si mon contrôleur de vue racine avait déjà une boîte de dialogue modale, il serait bloqué, donc je passerait en haut de tous les contrôleurs de vue modale à l'aide de ce code:
la source
vous pouvez trouver le meilleur contrôleur de vue en utilisant
la source
self
n'a aucunenavigationController
propriété.Une autre solution repose sur la chaîne de répondeurs, qui peut ou non fonctionner selon ce qu'est le premier répondant:
Exemple de pseudo code:
la source
Rapide:
Usage:
la source