Як перевірити поточний клас контролера перегляду в Swift?


79

Наскільки мені відомо, це могло б працювати в Objective-C:

self.window.rootViewController.class == myViewController

Як я можу перевірити, чи поточний контролер подання є певним?


Ви намагаєтесь визначити, чи це екземпляр певного класу, чи конкретний екземпляр?
mc01

Відповіді:


83

Щоб перевірити клас у Swift, використовуйте "є" (як це пояснено в розділі "Перевірка типу" в главі під назвою Type Casting у Посібнику з програмування Swift)

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

4
Змінна self.windowне існує
user83039

@ user83039 Що тоді selfв цьому випадку? Куди ви кладете код? self.window і rootViewController знаходяться в AppDelegate. Потрібна додаткова інформація.
mc01

Я всередині контролера перегляду.
user83039

Тоді в цьому проблема - у 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

2
Чудово, це спрацювало для мене. Просто замість self.windowвикористанняself.view.window
Колтрейн

Як я можу адаптувати це до TabBar?
Даніель Спрінгер

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
Тоді використовуйте self.isKindOfClass
Кіран Тапа

1
self - це не обов'язково те, що показується, якщо я використовую цю функцію з іншого класу ...
user83039

Я фактично використовую обидва. Контролери навігації знаходяться всередині контролера панелі вкладок.
user83039

Що якщо я поміщу це всередину structвсередину класу?
user83039 02

11

Мені довелося знайти поточний viewController в AppDelegate. Я цим користувався

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

}

self - це не обов'язково те, що показується, якщо я використовую функцію з іншого класу ...
user83039

Дякую, це допомогло. Це особливо корисно для перевірки представленого в даний час 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(). Все, що мені потрібно було сказати, на якому екрані я перебуваю, і це мені ідеально підходить.


7

Свіфт 4, Свіфт 5

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

}

1

Для типів, які ви можете використовувати, isі якщо це ваш власний клас контролера перегляду, вам потрібно використовувати, 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

Перевірте той спосіб, який мені краще працював. Що таке

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

Моя пропозиція - це варіація відповіді Кірана вище. Я використав це у проекті.

Стрімкий 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)
            }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.