Wie überprüfen Sie die aktuelle View Controller-Klasse in Swift?


77

Soweit ich weiß, würde dies in Ziel-C funktionieren:

self.window.rootViewController.class == myViewController

Wie kann ich überprüfen, ob es sich bei dem aktuellen Ansichtscontroller um einen bestimmten handelt?


Versuchen Sie festzustellen, ob es sich um eine Instanz einer bestimmten Klasse oder um eine bestimmte Instanz handelt?
mc01

Antworten:


80

Verwenden Sie zum Überprüfen der Klasse in Swift "is" (wie unter "Überprüfen des Typs" im Kapitel "Typumwandlung im Swift-Programmierhandbuch" erläutert).

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

4
Die Variable self.windowexistiert nicht
user83039

@ user83039 Was ist dann selfin diesem Fall? Wo setzen Sie den Code ein? self.window und rootViewController befinden sich in AppDelegate. Benötigen Sie weitere Informationen.
mc01

Ich bin in einem View Controller.
user83039

Das ist dann das Problem - viewController haben kein Fenster, und jeder Code, den Sie dort einfügen, sagt nur über sich selbst aus, was nicht hilfreich ist. Siehe: stackoverflow.com/questions/20485585/… UND stackoverflow.com/questions/11637709/…
mc01

46

Aktualisiert für den Swift3-Compiler, der einen Anfall macht! und ?

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
Keine so etwas wie self.window
user83039

1
bist du in AppDelegate? Wenn nicht, können Sie Ihr AppDelegate herunterladen und so etwas tun.
Nhut Duong

2
Super, das hat bei mir funktioniert. Nur anstatt zu self.windowbenutzenself.view.window
Coltrane

Wie kann ich dies an eine TabBar anpassen?
Daniel Springer

1
@DanielSpringer wenn tabBarController.viewControllers? [TabBarController.selectedIndex] als? YourClass {}
Josh Wolff

26

Wenn Sie einen Navigationscontroller verwenden, können Sie problemlos über Ihre Ansichtscontroller iterieren. Und dann können Sie nach der bestimmten Instanz suchen als:

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

1
Ich habe kein Objekt, das aktuelle Fenster soll das Objekt sein.
user83039

1
Verwenden Sie self.isKindOfClass dann
Kiran Thapa

1
Selbst ist nicht unbedingt das, was gezeigt wird, wenn ich diese Funktion aus einer anderen Klasse verwende ...
user83039

Ich benutze eigentlich beide. Die Navigationssteuerungen befinden sich in der Registerkartensteuerung.
user83039

Was ist, wenn ich dies in ein structInneres der Klasse stecke?
user83039

11

Ich musste den aktuellen viewController in AppDelegate finden. Ich habe das benutzt

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

Versuche dies

if self is MyViewController {        

}

Selbst ist nicht unbedingt das, was angezeigt wird, wenn ich eine Funktion aus einer anderen Klasse verwende ...
user83039

Danke, das hat geholfen. Dies ist besonders nützlich, um den aktuell angezeigten viewController zu überprüfen. Ich konnte feststellen, ob der Controller ein UIAlertController war, um mehrere Präsentationen zu verhindern.
6.

7

Um von Thapas Antwort abzuweichen, müssen Sie in die Viewcontroller-Klasse wechseln, bevor Sie ...

   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

Swift 3

Ich bin mir nicht sicher, aber ich habe es schwer mit diesem. Ich habe so etwas gemacht:

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

Ich habe immer wieder den anfänglichen View Controller meiner App erhalten. Aus irgendeinem Grund wollte es der Root-View-Controller bleiben, egal was passiert. Also habe ich einfach eine globale Variable vom Typ String erstellt currentViewControllerund ihren Wert in jeder Variable selbst festgelegt viewDidLoad(). Ich musste nur sagen, auf welchem ​​Bildschirm ich mich befand und das funktioniert perfekt für mich.


6

Swift 4, Swift 5

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

}

1

Für Typen, die Sie verwenden können, isund wenn es sich um Ihre eigene Viewcontroller-Klasse handelt, müssen Sie Folgendes verwenden isKindOfClass:

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

1

Swift 3 | Überprüfen Sie, ob ein Ansichts-Controller der Stamm in sich selbst ist.

Sie können windowvon einem View Controller aus zugreifen , den Sie nur verwenden müssen self.view.window.

Kontext: Ich muss die Position einer Ansicht aktualisieren und eine Animation auslösen, wenn das Gerät gedreht wird. Ich möchte dies nur tun, wenn der View Controller aktiv ist.

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

Wenn Sie Ihr Gerät drehen, während MyViewController aktiv ist, werden die obigen Zeilen auf der Konsole gedruckt. Wenn MyViewController nicht aktiv ist, werden sie nicht angezeigt.

Wenn Sie neugierig sind, warum ich UIDeviceOrientationDidChangeanstelle von verwende .UIDeviceOrientationDidChange, schauen Sie sich diese Antwort an .


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

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

1

Überprüfen Sie den Weg, der für mich besser funktioniert hat. Was ist .selbst

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

Mein Vorschlag ist eine Variation von Kirans Antwort oben. Ich habe das in einem Projekt verwendet.

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
}  

0
 var top = window?.rootViewController
            while ((top?.presentedViewController) != nil) {
                top = top?.presentedViewController
            }
            
            if !(type(of: top!) === CallingVC.self) {
                top?.performSegue(withIdentifier: "CallingVC", sender: call)
            }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.