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?
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?
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
}
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
}
}
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) {
}
}
}
Try this
if self is MyViewController {
}
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 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.
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
Swift 4, Swift 5
let viewController = UIApplication.shared.keyWindow?.rootViewController
if viewController is MyViewController {
}
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
}
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)
}
}
Check that way that worked better for me What is .self
if ((self.window.rootViewController?.isKind(of: WebViewController.self))!)
{
//code
}
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")
}
Swift 5 and iOS 15
if self.navigationController?.presentedViewController != nil &&
self.navigationController?.presentedViewController is ChatViewController {
return
}
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)
}
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
}
var top = window?.rootViewController
while ((top?.presentedViewController) != nil) {
top = top?.presentedViewController
}
if !(type(of: top!) === CallingVC.self) {
top?.performSegue(withIdentifier: "CallingVC", sender: call)
}
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 viewWillAppear
s change a global variable to equal the respective enum.