12

So, I'm using the method bellow from UIApplication extension to get the top view controller:

    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
    if let navigationController = controller as? UINavigationController {
        return topViewController(controller: navigationController.visibleViewController)
    }
    if let tabController = controller as? UITabBarController {
        if let selected = tabController.selectedViewController {
            return topViewController(controller: selected)
        }
    }
    if let presented = controller?.presentedViewController {
        return topViewController(controller: presented)
    }
    return controller
}

But the problem is: It always returns UIViewController. But I need to check if it is MyViewController for example. How do I achieve that?

5 Answers 5

5

Do conditional casting on the return value to safely check its type.

if let currentVC = UIApplication.topViewController() as? MyViewController {
   //the type of currentVC is MyViewController inside the if statement, use it as you want to
}

Your whole function implementation is flawed, if it actually worked, it would lead to infinite recursion. Once you find out the type of your current top view controller in your if statements, you are calling the same function again with the current root controller as its input value. Your function only ever exists, if it reaches either a call from a view controller, whose class is none of the ones specified in your optional bindings.

Moreover, your whole implementation doesn't do anything at the moment. You find out the type of your root view controller, but than you upcast it by returning a value of type UIViewController.

Sign up to request clarification or add additional context in comments.

5 Comments

Your question doesn't reflect your actual problem it seems. Have a look at my updated answer. Your implementation is completely flawed. What are you actually trying to do? Are you trying to return your rootViewController with its exact type instead of type UIViewController?
Thanks for the insights, i'll take that in consideration to update the topViewController method.
@DávidPásztor I cannot use topViewController in Swift 4.
@SoftDev did you declare it as it is declared in the question itself?
Awesome sir it helps me lot.
2

You can do a conditional check with an if-let statement like this:

if let presented = controller?.presentedViewController as? MyViewController {
    // it is a MyViewController
}

You can also just directly check if the UIViewController is that type of class like this:

if controller?.presentedViewController is MyViewController {
    // it is a MyViewController
}

Comments

1

Try this:

if let presented = controller?.presentedViewController as? MyViewController {
    ...

Comments

1

You can check it in following ways

class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let navigationController = controller as? UINavigationController {
            return topViewController(controller: navigationController.visibleViewController)
        }
        else if let tabController = controller as? UITabBarController {
            if let selected = tabController.selectedViewController {
                return topViewController(controller: selected)
            }
        }
        else if let presented = controller?.presentedViewController {
            return topViewController(controller: presented)
        }
        return controller
}


        // Answer 
        if let topVC = AppDelegate.topViewController() as? MyViewController {
            // Here your topVC is MyViewController
        }


        // or 
        if let topVC = AppDelegate.topViewController() {

            if topVC is MyViewController {
                // Here your topVC is MyViewController
            }
        }

Comments

1

To use the UIViewController as MyViewController:

if let myViewController = UIApplication.topViewController() as? MyViewController { ... }

or if you just want to check that the UIViewController is of type MyViewController:

if UIApplication.topViewController() is MyViewController { ... }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.