Як отримати контролер root root?


109

Мені потрібен екземпляр контролера кореневого перегляду.

Я спробував такі підходи:

UIViewController *rootViewController = (UIViewController*)[[[UIApplication sharedApplication] keyWindow] rootViewController];

Повертає: null :

Також коли я намагаюся отримати масив контролерів:

NSArray *viewControllers = self.navigationController.viewControllers;

Він повертає лише один контролер, але це не мій контролер кореневого перегляду.

Якщо я спробую взяти з навігаційного контролера:

UIViewController *root = (UIViewController*)[self.navigationController.viewControllers objectAtIndex:0];

Повертає: null :

Будь-які ідеї чому? Що ще я можу спробувати отримати екземпляр мого контролера root view?

Дякую.


KeyWindow - це активне вікно, наприклад, коли ви показуєте UIAlertView, вікно UIAlertView є ключовим вікном, але це не вікно AppDelegate. Якщо ви хочете отримати rootViewController програми, ви можете скористатися [[UIApplication sharedApplication] delegate] window] rootViewController ] краще.
无 夜 之 星辰

Відповіді:


213

якщо ви намагаєтесь отримати доступ до rootViewControllerвстановленого вами додаткаDelegate. спробуйте це:

Ціль-С

YourViewController *rootController = (YourViewController*)[[(YourAppDelegate*)
                                   [[UIApplication sharedApplication]delegate] window] rootViewController];

Швидкий

let appDelegate  = UIApplication.sharedApplication().delegate as AppDelegate
let viewController = appDelegate.window!.rootViewController as YourViewController

Швидкий 3

let appDelegate  = UIApplication.shared.delegate as! AppDelegate
let viewController = appDelegate.window!.rootViewController as! YourViewController

Швидкий 4 та 4.2

let viewController = UIApplication.shared.keyWindow!.rootViewController as! YourViewController

Swift 5 та 5.1 та 5.2

let viewController = UIApplication.shared.windows.first!.rootViewController as! YourViewController

3
YourViewController * rootController = (YourViewController *) [[((YourAppDelegate *) [[UIApplication sharedApplication] delegate] window] rootViewController];
Крейг Мур

1
У Swift2 вам потрібно використовувати "дозволити appDelegate = UIApplication.sharedApplication (). Делегувати як! AppDelegate", щоб змусити розкрутити
Джекі

Чи є спосіб встановити два контролери таким чином, щоб ви могли перетягувати дані з обох на годинник?
Джонні Марін

1
Це рятівник. Дякую! Мені потрібні місяці, щоб знайти цей шматок смачного коду!
ItsMeDom

37

Ціль-С

UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController;

Швидкий 2.0

let viewController = UIApplication.sharedApplication().keyWindow?.rootViewController

Швидкий 5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
Це має бути головна відповідь. +1 Інші відповіді не спрацюють, якщо вам потрібно посилатись на контролер кореневого перегляду з іншого фреймворку, від якого залежить ваш основний додаток.
C. Tewalt

10

Як запропонував тут @ 0x7fffffff, якщо у вас є UINavigationController, це можна зробити простіше:

YourViewController *rootController =
    (YourViewController *)
        [self.navigationController.viewControllers objectAtIndex: 0];

Код у відповіді вище повертає контролер UINavigation (якщо у вас є), і якщо це те, що вам потрібно, ви можете використовувати self.navigationController.


5

Якщо у вас немає вагомих причин, у вашому кореневому контролері виконайте це:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(onTheEvent:)
                                             name:@"ABCMyEvent"
                                           object:nil];

І коли ви хочете повідомити про це:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ABCMyEvent"
                                                object:self];                


1

Швидкий спосіб зробити це, ви можете зателефонувати цьому з будь-якого місця, він повертається необов’язково, тому будьте уважні:

/// EZSwiftExtensions - Gives you the VC on top so you can easily push your popups
var topMostVC: UIViewController? {
    var presentedVC = UIApplication.sharedApplication().keyWindow?.rootViewController
    while let pVC = presentedVC?.presentedViewController {
        presentedVC = pVC
    }

    if presentedVC == nil {
        print("EZSwiftExtensions Error: You don't have any views set. You may be calling them in viewDidLoad. Try viewDidAppear instead.")
    }
    return presentedVC
}

Його включено як стандартну функцію в:

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3: Chage ViewController withOut Segue та відправте AnyObject Use: Identity MainPageViewController на цільовому ViewController

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "MainPageViewController") as! MainPageViewController

var mainPageNav = UINavigationController(rootViewController: mainPage)

self.present(mainPageNav, animated: true, completion: nil)

або якщо ви хочете змінити контролер перегляду та надіслати дані

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "MainPageViewController") as! MainPageViewController

let dataToSend = "**Any String**" or  var ObjectToSend:**AnyObject** 

mainPage.getData = dataToSend 

var mainPageNav = UINavigationController(rootViewController: mainPage)

self.present(mainPageNav, animated: true, completion: nil)  

Ти найкращий чувак :)
bsm-2000
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.