How do you check current view controller class in Swift?

IosSwift

Ios Problem Overview


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?

Ios Solutions


Solution 1 - Ios

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
}

Solution 2 - Ios

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
        }
    }

Solution 3 - Ios

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) {
                    
                }
            }
        }

Solution 4 - Ios

Try this

if self is MyViewController {        

}

Solution 5 - Ios

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!!!")
			}
		}
	}

Solution 6 - Ios

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.

Solution 7 - Ios

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

Solution 8 - Ios

Swift 4, Swift 5

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

}

Solution 9 - Ios

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
            }

Solution 10 - Ios

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.

Solution 11 - Ios

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

Solution 12 - Ios

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

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

Solution 13 - Ios

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)
        }

Solution 14 - Ios

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
}  

Solution 15 - Ios

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

Solution 16 - Ios

I chose to create my own enum to keep track of which view controller I was on:

enum currentViewController{
   case publicVC
   case homeVC
   case friendsVC
}

Then in each of your viewWillAppears change a global variable to equal the respective enum.

Solution 17 - Ios

After implementing and try is current viewController is open I find 100% solution

for example when receiving a new notification

here the implement using 'userNotificationCenter'

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
                            withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let userInfo = notification.request.content.userInfo
    
    // Change this to your preferred presentation option
    Messaging.messaging().appDidReceiveMessage(userInfo)
    
    let keyWindow = UIApplication.shared.connectedScenes
        .map({$0 as? UIWindowScene})
        .compactMap({$0})
        .first?.windows
        .filter({$0.isKeyWindow}).first
    
    guard let window = keyWindow else { return }
    
    if window.rootViewController?.children.last is MyViewController{
        print("Chat")
        completionHandler([])
    }else{
        print("Not not not Chat")
        completionHandler([.alert, .badge, .sound])
    }
 }

and simply to check try this

let keyWindow = UIApplication.shared.connectedScenes
        .map({$0 as? UIWindowScene})
        .compactMap({$0})
        .first?.windows
        .filter({$0.isKeyWindow}).first
    
    guard let window = keyWindow else { return }
    
    if window.rootViewController?.children.last is MyViewController{
        print("Yes Its current ViewController")
    }else{
        print("Not it's not Current ViewController")
    }

Solution 18 - Ios

Swift 5 and iOS 15

if self.navigationController?.presentedViewController != nil && 
        self.navigationController?.presentedViewController is ChatViewController {
            return
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser83039View Question on Stackoverflow
Solution 1 - Iosmc01View Answer on Stackoverflow
Solution 2 - IosNhut DuongView Answer on Stackoverflow
Solution 3 - IosKiran ThapaView Answer on Stackoverflow
Solution 4 - IosChristos ChadjikyriacouView Answer on Stackoverflow
Solution 5 - IosIvan ReyesView Answer on Stackoverflow
Solution 6 - IosTrev14View Answer on Stackoverflow
Solution 7 - IosKorinWView Answer on Stackoverflow
Solution 8 - IosPenggunaView Answer on Stackoverflow
Solution 9 - IosOwais MunawarView Answer on Stackoverflow
Solution 10 - IosDerek SoikeView Answer on Stackoverflow
Solution 11 - IosHemanshu LiyaView Answer on Stackoverflow
Solution 12 - IosΩlostAView Answer on Stackoverflow
Solution 13 - IosYuriy UlantsevView Answer on Stackoverflow
Solution 14 - IosDouglas FrariView Answer on Stackoverflow
Solution 15 - IosMuhammad QasimView Answer on Stackoverflow
Solution 16 - IosDavidView Answer on Stackoverflow
Solution 17 - IosAhmad MustafaView Answer on Stackoverflow
Solution 18 - Ioslogeshpalani31View Answer on Stackoverflow