J'ai des viewControllers
, et je n'utilise pas NavigationController
. Comment puis-je get le controller de vue visible dans les methods de délégué d'application (par exemple applicationWillResignActive
)?
Je sais comment le faire à partir NSNotification
, mais je pense que c'est la mauvaise façon.
Cela devrait le faire pour vous:
- (void)applicationWillResignActive:(UIApplication *)application { UIViewController *vc = [self visibleViewController:[UIApplication sharedApplication].keyWindow.rootViewController]; } - (UIViewController *)visibleViewController:(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 visibleViewController:lastViewController]; } if ([rootViewController.presentedViewController isKindOfClass:[UITabBarController class]]) { UITabBarController *tabBarController = (UITabBarController *)rootViewController.presentedViewController; UIViewController *selectedViewController = tabBarController.selectedViewController; return [self visibleViewController:selectedViewController]; } UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController; return [self visibleViewController:presentedViewController]; }
La réponse de @ aviatorken89 a bien fonctionné pour moi. Je devais le traduire en Swift – pour tous ceux qui débutent avec Swift:
Mise à jour pour Swift 3:
func getVisibleViewController(_ rootViewController: UIViewController?) -> UIViewController? { var rootVC = rootViewController if rootVC == nil { rootVC = UIApplication.shared.keyWindow?.rootViewController } if rootVC?.presentedViewController == nil { return rootVC } if let presented = rootVC?.presentedViewController { if presented.isKind(of: UINavigationController.self) { let navigationController = presented as! UINavigationController return navigationController.viewControllers.last! } if presented.isKind(of: UITabBarController.self) { let tabBarController = presented as! UITabBarController return tabBarController.selectedViewController! } return getVisibleViewController(presented) } return nil }
Vieille réponse:
func applicationWillResignActive(application: UIApplication) { let currentViewController = getVisibleViewController(nil) } func getVisibleViewController(var rootViewController: UIViewController?) -> UIViewController? { if rootViewController == nil { rootViewController = UIApplication.sharedApplication().keyWindow?.rootViewController } if rootViewController?.presentedViewController == nil { return rootViewController } if let presented = rootViewController?.presentedViewController { if presented.isKindOfClass(UINavigationController) { let navigationController = presented as! UINavigationController return navigationController.viewControllers.last! } if presented.isKindOfClass(UITabBarController) { let tabBarController = presented as! UITabBarController return tabBarController.selectedViewController! } return getVisibleViewController(presented) } return nil }
Nous l'avons implémenté en tant qu'extension UIApplication:
import UIKit extension UIApplication { var visibleViewController: UIViewController? { guard let rootViewController = keyWindow?.rootViewController else { return nil } return getVisibleViewController(rootViewController) } private func getVisibleViewController(_ rootViewController: UIViewController) -> UIViewController? { if let presentedViewController = rootViewController.presentedViewController { return getVisibleViewController(presentedViewController) } if let navigationController = rootViewController as? UINavigationController { return navigationController.visibleViewController } if let tabBarController = rootViewController as? UITabBarController { return tabBarController.selectedViewController } return rootViewController } }
Voici une approche récursive, orientée protocole dans Swift. Peut être étendu aux types personnalisés, mais tout type de sous-class UIViewController devrait fonctionner avec le code ci-dessous.
public protocol ViewControllerContainer { var topMostViewController: UIViewController? { get } } extension UIViewController: ViewControllerContainer { public var topMostViewController: UIViewController? { if let presentedView = presentedViewController { return recurseViewController(presentedView) } return childViewControllers.last.map(recurseViewController) } } extension UITabBarController { public override var topMostViewController: UIViewController? { return selectedViewController.map(recurseViewController) } } extension UINavigationController { public override var topMostViewController: UIViewController? { return viewControllers.last.map(recurseViewController) } } extension UIWindow: ViewControllerContainer { public var topMostViewController: UIViewController? { return rootViewController.map(recurseViewController) } } func recurseViewController(viewController: UIViewController) -> UIViewController { return viewController.topMostViewController.map(recurseViewController) ?? viewController }
Si le controller de vue racine de votre application est un UINavigationController, vous pouvez utiliser ceci:
UIViewController *currentControllerName = ((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
et si vous utilisez UITabBarController que vous pouvez utiliser ceci:
UIViewController *currentControllerName = ((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
Voici une implémentation Swift 2.3 de la réponse de @ ProgrammierTier en tant qu'extension d'un UIViewController
extension UIViewController { var visibleViewController: UIViewController? { if presentedViewController == nil { return self } if let presented = presentedViewController { if presented.isKindOfClass(UINavigationController) { let navigationController = presented as! UINavigationController return navigationController.viewControllers.last } if presented.isKindOfClass(UITabBarController) { let tabBarController = presented as! UITabBarController return tabBarController.selectedViewController } return presented.visibleViewController } return nil } }
Pour l'get à partir de applicationWillResignActive
func applicationWillResignActive(application: UIApplication) { let visibleVC = application.keyWindow?.rootViewController?.visibleViewController }
modifié à partir de troop231
+ (UIViewController *)visibleViewController:(UIViewController *)rootViewController { if ([rootViewController isKindOfClass:[UINavigationController class]]) { UINavigationController *navigationController = (UINavigationController *)rootViewController; UIViewController *lastViewController = [[navigationController viewControllers] lastObject]; return [self visibleViewController:lastViewController]; } if ([rootViewController isKindOfClass:[UITabBarController class]]) { UITabBarController *tabBarController = (UITabBarController *)rootViewController; UIViewController *selectedViewController = tabBarController.selectedViewController; return [self visibleViewController:selectedViewController]; } if (rootViewController.presentedViewController != nil) { UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController; return [self visibleViewController:presentedViewController]; } return rootViewController; }