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?

user83039
quelle
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
}
mc01
quelle
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
        }
    }
Nhut Duong
quelle
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")
        }
    } 
}
Kiran Thapa
quelle
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!!!")
            }
        }
    }
Ivan Reyes
quelle
10

Versuche dies

if self is MyViewController {        

}
Christos Chadjikyriacou
quelle
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
KorinW
quelle
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.

Trev14
quelle
6

Swift 4, Swift 5

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

}
Dary
quelle
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
            }
Owais Munawar
quelle
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 .

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

            if aViewController .isKind(of: (MyClass?.classForCoder)!) {
                _ = navController?.popToViewController(aViewController, animated: true)
            }
        }
Hemanshu Liya
quelle
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
}
ΩlostA
quelle
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)
        }
Yuriy Ulantsev
quelle
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
}  
Douglas Frari
quelle
0
 var top = window?.rootViewController
            while ((top?.presentedViewController) != nil) {
                top = top?.presentedViewController
            }
            
            if !(type(of: top!) === CallingVC.self) {
                top?.performSegue(withIdentifier: "CallingVC", sender: call)
            }
Muhammad Qasim
quelle