Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the current visible viewController from AppDelegate

Tags:

ios

swift

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?

like image 792
Zakaria Avatar asked Sep 06 '17 14:09

Zakaria


People also ask

How do I get visible ViewController in Swift?

extension UIViewController { /// Top most ViewController func topMostViewController() -> UIViewController { if self. presentedViewController == nil { return self } if let navigation = self.

How do I get topViewController?

In addition, you can check for UINavigationController and ask for its topViewController or even check for UITabBarController and ask for selectedViewController . This will get you the view controller that is currently visible to the user.


2 Answers

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.

like image 131
Dávid Pásztor Avatar answered Oct 27 '22 00:10

Dávid Pásztor


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
}
like image 45
MSU_Bulldog Avatar answered Oct 27 '22 00:10

MSU_Bulldog