How to find topmost view controller on iOS

后端 未结 30 3031
遥遥无期
遥遥无期 2020-11-22 08:40

I\'ve run into a couple of cases now where it would be convenient to be able to find the \"topmost\" view controller (the one responsible for the current view), but haven\'t

30条回答
  •  佛祖请我去吃肉
    2020-11-22 09:14

    A lot of these answers are incomplete. Although this is in Objective-C, this is the best compilation of all of them that I could put together for right now, as a non-recursive block:

    • Link to Gist, in case it gets revised: https://gist.github.com/benguild/0d149bb3caaabea2dac3d2dca58c0816

    • Code for reference/comparison:

    UIViewController *(^topmostViewControllerForFrontmostNormalLevelWindow)(void) = ^UIViewController *{
        // NOTE: Adapted from various stray answers here:
        //   https://stackoverflow.com/questions/6131205/iphone-how-to-find-topmost-view-controller/20515681
    
        UIViewController *viewController;
    
        for (UIWindow *window in UIApplication.sharedApplication.windows.reverseObjectEnumerator.allObjects) {
            if (window.windowLevel == UIWindowLevelNormal) {
                viewController = window.rootViewController;
                break;
            }
        }
    
        while (viewController != nil) {
            if ([viewController isKindOfClass:[UITabBarController class]]) {
                viewController = ((UITabBarController *)viewController).selectedViewController;
            } else if ([viewController isKindOfClass:[UINavigationController class]]) {
                viewController = ((UINavigationController *)viewController).visibleViewController;
            } else if (viewController.presentedViewController != nil && !viewController.presentedViewController.isBeingDismissed) {
                viewController = viewController.presentedViewController;
            } else if (viewController.childViewControllers.count > 0) {
                viewController = viewController.childViewControllers.lastObject;
            } else {
                BOOL repeat = NO;
    
                for (UIView *view in viewController.view.subviews.reverseObjectEnumerator.allObjects) {
                    if ([view.nextResponder isKindOfClass:[UIViewController class]]) {
                        viewController = (UIViewController *)view.nextResponder;
    
                        repeat = YES;
                        break;
                    }
                }
    
                if (!repeat) {
                    break;
                }
            }
        }
    
        return viewController;
    };
    

提交回复
热议问题