How to get visible viewController from app delegate when using storyboard?
This should do it for you:
- (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];}
@aviatorken89's answer worked well for me. I had to translate it to Swift - for anybody starting out with Swift:
Updated for 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}
Old answer:
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}
We implemented it as an UIApplication extension:
import UIKitextension 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 }}