Scenario: The user taps on a button on a view controller. The view controller is the topmost (obviously) in the navigation stack. The tap invokes a utility class method call
Some of these answers only worked partly for me, combining them in the following class method in AppDelegate was the solution for me. It works on iPad, in UITabBarController views, in UINavigationController, en when presenting modals. Tested on iOS 10 and 13.
+ (UIViewController *)rootViewController {
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
if([rootViewController isKindOfClass:[UINavigationController class]])
rootViewController = ((UINavigationController *)rootViewController).viewControllers.firstObject;
if([rootViewController isKindOfClass:[UITabBarController class]])
rootViewController = ((UITabBarController *)rootViewController).selectedViewController;
if (rootViewController.presentedViewController != nil)
rootViewController = rootViewController.presentedViewController;
return rootViewController;
}
Usage:
[[AppDelegate rootViewController] presentViewController ...