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

据我所知,这在 Objective-C 中是可行的:

self.window.rootViewController.class == myViewController

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

148691 次浏览

要检查 Swift 中的类,请使用 “是”(正如在“快速编程指南中的类型转换”一章的“检查类型”中所解释的那样)

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

更新为 Swift 3编译器抛出一个适合! 和?

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

试试这个

if self is MyViewController {


}

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

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

}
}
}

我必须找到当前的视图控制器在应用委托。 我用了这个

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

要离开 Thapa 的回答,您需要在使用..。

   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

对于类型,你可以使用 is,如果它是你自己的 viewcontroller 类,那么你需要使用 isKindOfClass,比如:

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

Swift 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,看看 这个答案

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


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

Swift 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()中自己设置它的值。我只需要知道我在哪个屏幕上,这对我来说是完美的。

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

检查这种方式,更好地为我工作 什么是自我

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

斯威夫特4号,斯威夫特5号

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


}

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

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

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

enum currentViewController{
case publicVC
case homeVC
case friendsVC
}

然后在每个 viewWillAppear中更改一个全局变量以等于各自的枚举。

在实现并尝试当前 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")
}

Swift 5和 iOS 15

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