How to find topmost view controller on iOS

后端 未结 30 2309
遥遥无期
遥遥无期 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 08:59

    This works great for finding the top viewController 1 from any root view controlle

    + (UIViewController *)topViewControllerFor:(UIViewController *)viewController
    {
        if(!viewController.presentedViewController)
            return viewController;
        return [MF5AppDelegate topViewControllerFor:viewController.presentedViewController];
    }
    
    /* View Controller for Visible View */
    
    AppDelegate *app = [UIApplication sharedApplication].delegate;
    UIViewController *visibleViewController = [AppDelegate topViewControllerFor:app.window.rootViewController]; 
    
    0 讨论(0)
  • 2020-11-22 09:00

    This answer includes childViewControllers and maintains a clean and readable implementation.

    + (UIViewController *)topViewController
    {
        UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    
        return [rootViewController topVisibleViewController];
    }
    
    - (UIViewController *)topVisibleViewController
    {
        if ([self isKindOfClass:[UITabBarController class]])
        {
            UITabBarController *tabBarController = (UITabBarController *)self;
            return [tabBarController.selectedViewController topVisibleViewController];
        }
        else if ([self isKindOfClass:[UINavigationController class]])
        {
            UINavigationController *navigationController = (UINavigationController *)self;
            return [navigationController.visibleViewController topVisibleViewController];
        }
        else if (self.presentedViewController)
        {
            return [self.presentedViewController topVisibleViewController];
        }
        else if (self.childViewControllers.count > 0)
        {
            return [self.childViewControllers.lastObject topVisibleViewController];
        }
    
        return self;
    }
    
    0 讨论(0)
  • 2020-11-22 09:01

    you could find the top most view controller by using

    NSArray *arrViewControllers=[[self navigationController] viewControllers];
    UIViewController *topMostViewController=(UIViewController *)[arrViewControllers objectAtIndex:[arrViewControllers count]-1];
    
    0 讨论(0)
  • 2020-11-22 09:02

    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
    }
    
    0 讨论(0)
  • 2020-11-22 09:03

    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.

    0 讨论(0)
  • 2020-11-22 09:03

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题