137 votes

Obtenir le UIViewController actuellement affiché à l'écran dans AppDelegate.m

L'actuel UIViewController sur l'écran doivent répondre aux notifications push des APN, en définissant des vues de badges. Mais comment puis-je obtenir le UIViewController en méthode application:didReceiveRemoteNotification : de AppDelegate.m ?

J'ai essayé d'utiliser self.window.rootViewController pour obtenir l'affichage actuel UIViewController il peut s'agir d'un UINavigationViewController ou un autre type de contrôleur de vue. Et je découvre que le visibleViewController propriété de UINavigationViewController peut être utilisé pour obtenir le UIViewController sur l'écran. Mais que faire s'il ne s'agit pas d'une UINavigationViewController ?

Toute aide est appréciée ! Le code correspondant est le suivant.

AppDelegate.m

...
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    //I would like to find out which view controller is on the screen here.

    UIViewController *vc = [(UINavigationViewController *)self.window.rootViewController visibleViewController];
    [vc performSelector:@selector(handleThePushNotification:) withObject:userInfo];
}
...

ViewControllerA.m

- (void)handleThePushNotification:(NSDictionary *)userInfo{

    //set some badge view here

}

4voto

Dima Points 10869

Pourquoi ne pas simplement gérer le code de la notification push dans le délégué de l'application ? Est-il directement lié à une vue ?

Vous pouvez vérifier si la vue d'un UIViewController est actuellement visible en vérifiant si l'attribut window a une valeur. Voir plus aquí .

4voto

Ashok Kumar S Points 514

Juste un complément à la réponse de @zirinisp.

Créez un fichier, nommez-le UIWindowExtension.swift et collez le bout de phrase suivant :

import UIKit

public extension UIWindow {
    public var visibleViewController: UIViewController? {
        return UIWindow.getVisibleViewControllerFrom(self.rootViewController)
    }

    public static func getVisibleViewControllerFrom(vc: UIViewController?) -> UIViewController? {
        if let nc = vc as? UINavigationController {
            return UIWindow.getVisibleViewControllerFrom(nc.visibleViewController)
        } else if let tc = vc as? UITabBarController {
            return UIWindow.getVisibleViewControllerFrom(tc.selectedViewController)
        } else {
            if let pvc = vc?.presentedViewController {
                return UIWindow.getVisibleViewControllerFrom(pvc)
            } else {
                return vc
            }
        }
    }
}

func getTopViewController() -> UIViewController? {
    let appDelegate = UIApplication.sharedApplication().delegate
    if let window = appDelegate!.window {
        return window?.visibleViewController
    }
    return nil
}

Utilisez-le partout comme :

if let topVC = getTopViewController() {

}

Merci à @zirinisp.

3voto

Bseaborn Points 53

Concernant l'article de NSNotificationCenter ci-dessus (désolé, je ne trouve pas où poster un commentaire sous cet article...)

Au cas où certains obtiendraient l'erreur -[NSConcreteNotification allKeys] en quelque sorte. Changez ça :

-(void)didReceiveRemoteNotification:(NSDictionary *)userInfo

à ça :

-(void)didReceiveRemoteNotification:(NSNotification*)notif {
NSDictionary *dict = notif.userInfo;
}

3voto

CodeOverRide Points 377

Ça a marché pour moi. J'ai de nombreuses cibles qui ont des contrôleurs différents, donc les réponses précédentes ne semblaient pas fonctionner.

Vous voulez d'abord que ce soit dans votre classe AppDelegate :

var window: UIWindow?

puis, dans votre fonction

let navigationController = window?.rootViewController as? UINavigationController
if let activeController = navigationController!.visibleViewController {
    if activeController.isKindOfClass( MyViewController )  {
        println("I have found my controller!")    
   }
}

3voto

Mayur Deshmukh Points 973

C'est le meilleur moyen possible que j'ai essayé. Si cela peut aider quelqu'un...

+ (UIViewController*) topMostController
{
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X