[ios] How do you check current view controller class in Swift?

As far as I know, this would work in Objective-C:

self.window.rootViewController.class == myViewController

How can I check if the current view controller is a specific one?

This question is related to ios swift

The answer is


My suggestion is a variation on Kiran's answer above. I used this in a project.

Swift 5

// convenience property API on my class object to provide access to the my WindowController (MyController).
var myXWindowController: MyController? {

    var myWC: MyController?                
    for viewController in self.windowControllers {
        if ((viewController as? MyController) != nil) {
            myWC = viewController as? MyController
            break
        }
    }

    return myWC
}

// example of use
guard let myController = myXWindowController else {
    reportAssertionFailure("Failed to get MyXController from WindowController.")
    return
}  

For types you can use is and if it is your own viewcontroller class then you need to use isKindOfClass like:

let vcOnTop = self.embeddedNav.viewControllers[self.embeddedNav.viewControllers.count-1]
            if vcOnTop.isKindOfClass(VcShowDirections){
                return
            }

Updated for swift3 compiler throwing a fit around ! and ?

if let wd = UIApplication.shared.delegate?.window {
        var vc = wd!.rootViewController
        if(vc is UINavigationController){
            vc = (vc as! UINavigationController).visibleViewController

        }

        if(vc is LogInViewController){
            //your code
        }
    }

I had to find the current viewController in AppDelegate. I used this

//at top of class
var window:UIWindow?

// inside my method/function
if let viewControllers = window?.rootViewController?.childViewControllers {
    for viewController in viewControllers {
        if viewController.isKindOfClass(MyViewControllerClass) {
            println("Found it!!!")
            }
        }
    }

Swift 4, Swift 5

let viewController = UIApplication.shared.keyWindow?.rootViewController
if viewController is MyViewController {

}

Swift 3

Not sure about you guys, but I'm having a hard time with this one. I did something like this:

if let window = UIApplication.shared.delegate?.window {
    if var viewController = window?.rootViewController {
        // handle navigation controllers
        if(viewController is UINavigationController){
            viewController = (viewController as! UINavigationController).visibleViewController!
        }
        print(viewController)
    }
}

I kept getting the initial view controller of my app. For some reason it wanted to stay the root view controller no matter what. So I just made a global string type variable currentViewController and set its value myself in each viewDidLoad(). All I needed was to tell which screen I was on & this works perfectly for me.


You can easily iterate over your view controllers if you are using a navigation controller. And then you can check for the particular instance as:
Swift 5

 if let viewControllers = navigationController?.viewControllers {
            for viewController in viewControllers {
                if viewController.isKind(of: LoginViewController.self) {
                    
                }
            }
        }

To go off of Thapa's answer, you need to cast to the viewcontroller class before using...

   if let wd = self.view.window {
        var vc = wd.rootViewController!
        if(vc is UINavigationController){
            vc = (vc as! UINavigationController).visibleViewController
        }
        if(vc is customViewController){
            var viewController : customViewController = vc as! customViewController

To check the class in Swift, use "is" (as explained under "checking Type" in the chapter called Type Casting in the Swift Programming Guide)

if self.window.rootViewController is MyViewController {
    //do something if it's an instance of that class
}

if let index = self.navigationController?.viewControllers.index(where: { $0 is MyViewController }) {
            let vc = self.navigationController?.viewControllers[vcIndex] as! MyViewController
            self.navigationController?.popToViewController(vc, animated: true)
        } else {
            self.navigationController?.popToRootViewController(animated: true)
        }

Check that way that worked better for me What is .self

if ((self.window.rootViewController?.isKind(of: WebViewController.self))!)
{
  //code
}

Try this

if self is MyViewController {        

}

Swift 3 | Check if a view controller is the root from within itself.

You can access window from within a view controller, you just need to use self.view.window.

Context: I need to update the position of a view and trigger an animation when the device is rotated. I only want to do this if the view controller is active.

class MyViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(
            self, 
            selector: #selector(deviceDidRotate), 
            name: .UIApplicationDidChangeStatusBarOrientation, 
            object: nil
        )
    }

    func deviceDidRotate() {
        guard let window = self.view.window else { return }

        // check if self is root view controller
        if window.rootViewController == self {
            print("vc is self")
        }

        // check if root view controller is instance of MyViewController
        if window.rootViewController is MyViewController {
            print("vc is MyViewController")
        }
    }
}

If you rotate your device while MyViewController is active, you will see the above lines print to the console. If MyViewController is not active, you will not see them.

If you're curious why I'm using UIDeviceOrientationDidChange instead of .UIDeviceOrientationDidChange, look at this answer.


let viewControllers = navController?.viewControllers
        for aViewController in viewControllers! {

            if aViewController .isKind(of: (MyClass?.classForCoder)!) {
                _ = navController?.popToViewController(aViewController, animated: true)
            }
        }

 var top = window?.rootViewController
            while ((top?.presentedViewController) != nil) {
                top = top?.presentedViewController
            }
            
            if !(type(of: top!) === CallingVC.self) {
                top?.performSegue(withIdentifier: "CallingVC", sender: call)
            }