user462455
user462455

Reputation: 13588

Get reference to top viewcontroller in iOS

How do I get reference to top visible view controller in my app. I saw some solutions which make use of navigationcontroller.[top|visible]viewcontroller. But I don't use navigation controllers in my app.

This seems like a pretty common use case, and I find it strange it is difficult to get access to top|visible view controller

Upvotes: 1

Views: 3974

Answers (4)

Haofree
Haofree

Reputation: 1

-(UIViewController *) getTopMostController
{
    UIWindow *topWindow = [UIApplication sharedApplication].keyWindow;
    if (topWindow.windowLevel != UIWindowLevelNormal)
    {
        topWindow = [self returnWindowWithWindowLevelNormal];
    }

    UIViewController *topController = topWindow.rootViewController;
    if(topController == nil)
    {
        topWindow = [UIApplication sharedApplication].delegate.window;
        if (topWindow.windowLevel != UIWindowLevelNormal)
        {
            topWindow = [self returnWindowWithWindowLevelNormal];
        }
        topController = topWindow.rootViewController;
    }

    while(topController.presentedViewController)
    {
        topController = topController.presentedViewController;
    }

    if([topController isKindOfClass:[UINavigationController class]])
    {
        UINavigationController *nav = (UINavigationController*)topController;
        topController = [nav.viewControllers lastObject];

        while(topController.presentedViewController)
        {
            topController = topController.presentedViewController;
        }
    }

    return topController;
}

-(UIWindow *) returnWindowWithWindowLevelNormal
{
    NSArray *windows = [UIApplication sharedApplication].windows;
    for(UIWindow *topWindow in windows)
    {
        if (topWindow.windowLevel == UIWindowLevelNormal)
            return topWindow;
    }
    return [UIApplication sharedApplication].keyWindow;
}

Upvotes: 0

Haofree
Haofree

Reputation: 1

-(UIViewController *)getCurrentViewController
{
    UIViewController *result = nil;
    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal)
    {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for(UIWindow * tmpWin in windows)
        {
            if (tmpWin.windowLevel == UIWindowLevelNormal)
            {
                window = tmpWin;
                break;
            }
        }
    }
    UIView *frontView = [[window subviews] objectAtIndex:0];
    id nextResponder = [frontView nextResponder];

    if ([nextResponder isKindOfClass:[UIViewController class]])
        result = nextResponder;
    else
        result = window.rootViewController;
    return result;
}

Upvotes: 0

gklka
gklka

Reputation: 2564

This should also follow your modal views and navigation controllers (if any):

- (UIViewController *)deepestPresentedViewControllerOf:(UIViewController *)viewController
{
    if (viewController.presentedViewController) {
        return [self deepestPresentedViewControllerOf:viewController.presentedViewController];
    } else {
        return viewController;
    }
}

- (UIViewController *)topViewController
{
    UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
    UIViewController *deepestPresentedViewController = [self deepestPresentedViewControllerOf:rootViewController];
    if ([deepestPresentedViewController isKindOfClass:[UINavigationController class]]) {
        return ((UINavigationController *)deepestPresentedViewController).topViewController;
    } else {
        return deepestPresentedViewController;
    }
}

Upvotes: 3

rob mayoff
rob mayoff

Reputation: 385500

You should probably be using the delegate pattern here (giving the child view controller a reference to an object that it can call on). If you edit your post to explain why you think you need a reference to the top view controller, we can give you advice about how to use the delegate pattern in your situation.

But for now I'll just give you the rope you need to hang yourself:

UIViewController *topVC = [UIApplication sharedApplication].keyWindow.rootViewController;

Upvotes: 1

Related Questions