【问题标题】:How do you check current view controller class in Swift?如何在 Swift 中检查当前的视图控制器类?
【发布时间】:2015-02-27 05:34:59
【问题描述】:

据我所知,这适用于 Objective-C:

self.window.rootViewController.class == myViewController

如何检查当前视图控制器是否是特定的?

【问题讨论】:

  • 您是在尝试确定它是特定类的实例还是特定实例?

标签: ios swift


【解决方案1】:

要检查 Swift 中的类,请使用 "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
}

【讨论】:

  • 变量self.window不存在
  • @user83039 那么在这种情况下self 是什么?你把代码放在哪里? self.window 和 rootViewController 在 AppDelegate 中。需要更多信息。
  • 我在一个视图控制器里面。
  • 这就是问题所在 - viewControllers 没有窗口,你放在那里的任何代码只会告诉你它本身,这没有帮助。请参阅:stackoverflow.com/questions/20485585/…stackoverflow.com/questions/11637709/…
【解决方案2】:

针对 swift3 编译器进行了更新!和 ?

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

【讨论】:

  • 没有 self.window 之类的东西
  • 您在 AppDelegate 中吗?如果没有,您可以获取 AppDelegate 并执行类似操作。
  • 太棒了,这对我有用。只是代替self.window 使用self.view.window
  • 我怎样才能使它适应 TabBar?
  • @DanielSpringer if let tabBarController.viewControllers?[tabBarController.selectedIndex] as?你的班级{}
【解决方案3】:

如果您使用导航控制器,您可以轻松地迭代视图控制器。然后您可以检查特定实例:
Swift 5

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

【讨论】:

  • 我没有对象,当前窗口应该是对象。
  • 然后使用 self.isKindOfClass
  • self 不一定是我使用另一个类的函数时所显示的内容......
  • 我实际上都在使用。导航控制器位于标签栏控制器内。
  • 如果我把它放在类的struct 里面会怎样?
【解决方案4】:

我必须在 AppDelegate 中找到当前的 viewController。 我用过这个

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

【讨论】:

    【解决方案5】:

    试试这个

    if self is MyViewController {        
    
    }
    

    【讨论】:

    • self 不一定是我使用另一个类的函数时显示的内容...
    • 谢谢,这有帮助。这对于检查当前呈现的 viewController 特别有用。我能够判断控制器是否是 UIAlertController 以防止多次演示。
    【解决方案6】:

    要摆脱 Thapa 的回答,您需要在使用之前强制转换为 viewcontroller 类...

       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
    

    【讨论】:

      【解决方案7】:

      斯威夫特 3

      不确定你们的情况,但我很难接受这个。我做了这样的事情:

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

      我不断获得我的应用程序的初始视图控制器。出于某种原因,它无论如何都想保留根视图控制器。所以我只是创建了一个全局字符串类型变量currentViewController,并在每个viewDidLoad() 中自己设置它的值。我只需要知道我在哪个屏幕上,这对我来说非常适合。

      【讨论】:

        【解决方案8】:

        斯威夫特 4,斯威夫特 5

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

        【讨论】:

          【解决方案9】:

          对于类型,您可以使用is,如果它是您自己的视图控制器类,那么您需要使用isKindOfClass,例如:

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

          【讨论】:

            【解决方案10】:

            斯威夫特 3 |检查视图控制器是否是其自身的根。

            您可以从视图控制器中访问window,您只需要使用self.view.window

            上下文:我需要更新视图的位置并在设备旋转时触发动画。如果视图控制器处于活动状态,我只想这样做。

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

            如果您在 MyViewController 处于活动状态时旋转设备,您将看到上面的行打印到控制台。如果 MyViewController 未激活,您将看不到它们。

            如果您好奇我为什么使用UIDeviceOrientationDidChange 而不是.UIDeviceOrientationDidChange,请查看this answer

            【讨论】:

              【解决方案11】:
              let viewControllers = navController?.viewControllers
                      for aViewController in viewControllers! {
              
                          if aViewController .isKind(of: (MyClass?.classForCoder)!) {
                              _ = navController?.popToViewController(aViewController, animated: true)
                          }
                      }
              

              【讨论】:

                【解决方案12】:

                检查哪种方式对我更有效What is .self

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

                【讨论】:

                  【解决方案13】:
                  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)
                          }
                  

                  【讨论】:

                    【解决方案14】:

                    我的建议是上面 Kiran 的回答的变体。我在一个项目中使用了它。

                    斯威夫特 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
                    }  
                    

                    【讨论】:

                      【解决方案15】:
                       var top = window?.rootViewController
                                  while ((top?.presentedViewController) != nil) {
                                      top = top?.presentedViewController
                                  }
                                  
                                  if !(type(of: top!) === CallingVC.self) {
                                      top?.performSegue(withIdentifier: "CallingVC", sender: call)
                                  }
                      

                      【讨论】:

                        【解决方案16】:

                        我选择创建自己的枚举来跟踪我在哪个视图控制器上:

                        enum currentViewController{
                           case publicVC
                           case homeVC
                           case friendsVC
                        }
                        

                        然后在您的每个viewWillAppears 中更改一个全局变量以等于相应的枚举。

                        【讨论】:

                          【解决方案17】:

                          实施并尝试当前 viewController 是否打开后,我找到了 100% 的解决方案

                          例如收到新通知时

                          这里是使用'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])
                              }
                           }
                          

                          只是为了检查试试这个

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

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2012-10-06
                            • 2012-11-07
                            • 2017-07-09
                            • 2015-02-27
                            • 2012-12-02
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多