如何在Swift中检查当前的视图控制器类?


77

据我所知,这将在Objective-C中运行:

self.window.rootViewController.class == myViewController

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


您是否要确定它是特定类的实例还是特定实例?
mc01

Answers:


80

要在Swift中检查类,请使用“ is”(如《 Swift编程指南》中“类型转换”一章中“检查类型”中所述)

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

4
该变量self.window不存在
2014年

@ user83039那么self在这种情况下是什么?您将代码放在哪里?self.window和rootViewController在AppDelegate中。需要更多信息。
mc01 2014年

我在一个视图控制器中。
user83039 2014年

那就是问题所在-viewControllers没有窗口,您放置在其中的任何代码都只会告诉您有关自身的信息,这无济于事。请参阅:stackoverflow.com/questions/20485585/...stackoverflow.com/questions/11637709/...
MC01

46

更新为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
        }
    }

1
没有诸如self.window之类的东西
user83039

1
您在AppDelegate中吗?如果没有,您可以获取AppDelegate并执行类似的操作。
Nhut Duong 2015年

2
太棒了,这对我有用。只是,而不是self.window使用self.view.window
雷恩

如何使它适应TabBar?
丹尼尔·斯普林格'18

1
@DanielSpringer是否让tabBarController.viewControllers?[tabBarController.selectedIndex]为?YourClass {}
乔什·沃尔夫

26

如果您使用的是导航控制器,则可以轻松地遍历视图控制器。然后,您可以按以下方式检查特定实例:

if let viewControllers = navigationController?.viewControllers {
    for viewController in viewControllers {
        // some process
        if viewController.isKindOfClass(MenuViewController) {
            println("yes it is")
        }
    } 
}

1
我没有对象,当前窗口应该是该对象。
user83039'1

1
然后使用self.isKindOfClass
Kiran Thapa,

1
如果我正在使用另一个类中的函数,则self不一定是显示的内容
user83039'1

我实际上都在用。导航控制器在选项卡栏控制器内部。
user83039 2015年

如果我将其放在struct班级内部怎么办?
user83039 2015年

11

我必须在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!!!")
            }
        }
    }

10

试试这个

if self is MyViewController {        

}

如果我正在使用另一个类的函数,则自我不一定是要显示的内容
user83039 2015年

谢谢,这有所帮助。这对于检查当前显示的viewController特别有用。我能够判断该控制器是否为UIAlertController,以防止出现多个演示文稿。
6rchid

7

要摆脱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()。我所需要的只是告诉我在哪个屏幕上,这对我来说非常合适。


6

雨燕4,雨燕5

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

}

1

对于类型,您可以使用is,如果它是您自己的viewcontroller类,则需要使用isKindOfClass类似:

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

1

雨燕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,请看这个答案


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

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

1

检查对我更有效的方式什么是.self

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

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

0

我的建议是对上述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
}  

0
 var top = window?.rootViewController
            while ((top?.presentedViewController) != nil) {
                top = top?.presentedViewController
            }
            
            if !(type(of: top!) === CallingVC.self) {
                top?.performSegue(withIdentifier: "CallingVC", sender: call)
            }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.