1. By the response chain method
@implementation UIView (SYGetController)

- (UIViewController *)currentController {
    UIResponder *next = [self nextResponder];
    do {
        if ([next isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)next;
        }
        next = [next nextResponder];
    } while(next ! = nil);return nil;
}
@end
Copy the code
  1. Use recursive thinking to find the current view controller
+ (UIViewController *)currentViewController {
    UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
    UIViewController *currentVC = [self _findCurrentShowingViewControllerFromVC:vc];
    return currentVC;
}

+ (UIViewController *)_findCurrentShowingViewControllerFromVC:(UIViewController *)vc {
    UIViewController *currentVC;
    if([vc presentedViewController]) {UIViewController *nextVC = [vc presentedViewController]; currentVC = [self _findCurrentShowingViewControllerFromVC:nextVC]; }else if([vc isKindOfClass:[UITabBarController Class]]) {// Determine the current root view is UITabBarController UIViewController *nextVC = [(UITabBarController*)vc selectedViewController]; currentVC = [self _findCurrentShowingViewControllerFromVC:nextVC]; }else if([vc isKindOfClass:[UINavigationController Class]]) {// Determine the current root view is UINavigationController UIViewController *nextVC = [(UINavigationController *)vc visibleViewController]; currentVC = [self _findCurrentShowingViewControllerFromVC:nextVC]; }else {
        currentVC = vc;
    }
    return vc;
}
Copy the code
  1. The traversal method gets
+ (UIViewController *)_findCurrentShowingViewControllerFromVC:(UIViewController *)vc {
    while (1) {
        if (vc.presentedViewController) {
            vc = vc.presentedViewController;
        } else if ([vc isKindOfClass:[UITabBarController class]]) {
            vc = ((UITabBarController *)vc).selectedViewController;
        } else if ([vc isKindOfClass:[UINavigationController class]]) {
            vc = ((UINavigationController *)vc).visibleViewController;
        } else if (vc.childViewControllers.count > 0) {
            vc = vc.childViewControllers.lastObject;
        } else {
            break; }}return vc;
}
Copy the code

Supplement: PresentedViewController and presentingViewController If I present from controller A to controller B, A’s presentedViewController is B, and B’s present ViewController is A.