How to find topmost view controller on iOS
I think you need a combination of the accepted answer and @fishstix's
+ (UIViewController*) topMostController{ UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } return topController;}
Swift 3.0+
func topMostController() -> UIViewController? { guard let window = UIApplication.shared.keyWindow, let rootViewController = window.rootViewController else { return nil } var topController = rootViewController while let newTopController = topController.presentedViewController { topController = newTopController } return topController}
To complete JonasG's answer (who left out tab bar controllers while traversing), here is my version of returning the currently visible view controller:
- (UIViewController*)topViewController { return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];}- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController { if ([rootViewController isKindOfClass:[UITabBarController class]]) { UITabBarController* tabBarController = (UITabBarController*)rootViewController; return [self topViewControllerWithRootViewController:tabBarController.selectedViewController]; } else if ([rootViewController isKindOfClass:[UINavigationController class]]) { UINavigationController* navigationController = (UINavigationController*)rootViewController; return [self topViewControllerWithRootViewController:navigationController.visibleViewController]; } else if (rootViewController.presentedViewController) { UIViewController* presentedViewController = rootViewController.presentedViewController; return [self topViewControllerWithRootViewController:presentedViewController]; } else { return rootViewController; }}
iOS 4 introduced the rootViewController property on UIWindow:
[UIApplication sharedApplication].keyWindow.rootViewController;
You'll need to set it yourself after you create the view controller though.