Existe-t-il un moyen d'obtenir le contrôleur de vue actuel à partir de AppDelegate? Je sais qu'il existe rootViewController, mais ce n'est pas ce que je recherche.
Si vous avez UINavigationController dans appDelegate, utilisez sa propriété topViewController ou visibleViewController
Si le contrôleur de vue racine de votre application est une UINavigationController
, vous pouvez procéder comme suit:
((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
De même, s'il s'agit d'une UITabBarController
, vous pouvez faire ceci:
((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
Bien sûr, un casting explicite comme celui-ci est sale. Le mieux serait de capturer la référence vous-même en utilisant des types forts.
Cela pourrait aider
- (UIViewController *)topViewController{
return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController *)topViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil) {
return rootViewController;
}
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self topViewController:lastViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
return [self topViewController:presentedViewController];
}
Version rapide:
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
Extrait de: https://Gist.github.com/snikch/3661188
Faire une extension:
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(nav.visibleViewController)
}
if let tab = base as? UITabBarController {
let moreNavigationController = tab.moreNavigationController
if let top = moreNavigationController.topViewController where top.view.window != nil {
return topViewController(top)
} else if let selected = tab.selectedViewController {
return topViewController(selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(presented)
}
return base
}
}
Utilisation:
if let rootViewController = UIApplication.topViewController() {
//do sth with root view controller
}
Obtenez l'objet appDelegate:
MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Comme suggéré par Beryllium, vous pouvez utiliser les propriétés du contrôleur UINavigationController pour accéder à votre contrôleur de vue actuel.
Donc, le code ressemblerait à ceci:
id myCurrentController = tmpDelegate.myNavigationController.topViewController;
ou:
NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
Vous pouvez obtenir le contrôleur de vue actuel à partir de rootViewController en cherchant le programme presentsViewController, comme ceci:
UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (parentViewController.presentedViewController != nil){
parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;
Ça marche avec moi J'espère que ça aide :)
Solution rapide:
self.window.rootViewController.presentedViewController.
Cela devrait vous donner ce dont vous avez besoin.
Pour quiconque pas utilisant un UINavigationController
mais son contrôleur de vue par défaut est un UIViewController
, vous pouvez vérifier quel contrôleur de vue est actif (ou présenté) avec les éléments suivants dans AppDelegate
:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
if let rootViewController = self.window!.rootViewController {
if let presentedViewController = rootViewController.presentedViewController {
return presentedViewController.supportedInterfaceOrientations()
}
} // Else current view controller is DefaultViewController
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
Comme vous pouvez le constater, je vérifie le contrôleur de vue actuel afin de prendre en charge différentes orientations d'interface pour des contrôleurs de vue spécifiques. Pour toute autre personne intéressée par l'utilisation de cette méthode pour prendre en charge des éléments spécifiques, les éléments suivants doivent être placés dans chaque contrôleur de vue nécessitant une orientation spécifique.
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
Remarque: Ce code a été écrit avec Swift 1.2
J'ai souvent besoin de récupérer le contrôleur de vue actuellement affiché. Cela pourrait signifier le contrôleur de vue situé en haut de la pile du contrôleur UINavigationController actuel, le contrôleur de vue actuellement présenté, etc. J'ai donc écrit cette fonction qui la définit la plupart du temps et que vous pouvez utiliser à l'intérieur d'une extension UIViewController.
Code dans Swift 3 :
func currentViewController(
_ viewController: UIViewController? =
UIApplication.shared.keyWindow?.rootViewController)
-> UIViewController? {
guard let viewController =
viewController else { return nil }
if let viewController =
viewController as? UINavigationController {
if let viewController =
viewController.visibleViewController {
return currentViewController(viewController)
} else {
return currentViewController(
viewController.topViewController)
}
} else if let viewController =
viewController as? UITabBarController {
if let viewControllers =
viewController.viewControllers,
viewControllers.count > 5,
viewController.selectedIndex >= 4 {
return currentViewController(
viewController.moreNavigationController)
} else {
return currentViewController(
viewController.selectedViewController)
}
} else if let viewController =
viewController.presentedViewController {
return viewController
} else if viewController.childViewControllers.count > 0 {
return viewController.childViewControllers[0]
} else {
return viewController
}
}
Appelez-le avec: currentViewController()
Extension d'UIApplication dans Swift 4+ syntaxe basée sur la solution de A.G
public extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
let moreNavigationController = tab.moreNavigationController
if let top = moreNavigationController.topViewController, top.view.window != nil {
return topViewController(base: top)
} else if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
Exemple d'utilisation:
if let rootViewController = UIApplication.topViewController() {
//do something with rootViewController
}