Come ottenere il controller di visualizzazione di root?


109

Ho bisogno di un'istanza del controller di visualizzazione di root.

Ho provato questi approcci:

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

Restituisce: null :

Anche quando provo a ottenere una serie di controller:

NSArray *viewControllers = self.navigationController.viewControllers;

Restituisce solo un controller, ma non è il mio controller di visualizzazione principale.

Se provo a prendere dal controller di navigazione:

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

Restituisce: null :

Qualche idea sul perché? Cos'altro potrei provare a ottenere un'istanza del mio controller di visualizzazione root?

Grazie.


La keyWindow è la finestra attiva, ad esempio, quando mostri un UIAlertView, la finestra di UIAlertView è la keyWindow ma non è la finestra di AppDelegate. Se vuoi ottenere il rootViewController dell'applicazione, forse usa [[UIApplication sharedApplication] delegate] window] rootViewController ] è meglio.
无 夜 之 星辰

Risposte:


213

se stai tentando di accedere al file che rootViewControllerhai impostato nella tua appDelegate. prova questo:

Objective-C

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

veloce

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

Swift 3

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

Swift 4 e 4.2

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

Swift 5 e 5.1 e 5.2

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

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

1
In Swift2, devi usare "let appDelegate = UIApplication.sharedApplication (). Delegate as! AppDelegate", per forzare lo scartamento
Jacky

Esiste un modo per assegnare due controller in questo modo in modo da poter estrarre i dati da entrambi all'orologio?
Johnny Marin

1
Questo è un vero toccasana. Grazie! Mi ci sono voluti mesi per trovare questo delizioso codice!
ItsMeDom

37

Objective-C

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

Swift 2.0

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

Swift 5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
Questa dovrebbe essere la risposta migliore. +1 Le altre risposte non funzioneranno se è necessario fare riferimento al controller della vista principale da un framework diverso da cui dipende la tua app principale.
C. Tewalt

10

Come suggerito qui da @ 0x7fffffff, se hai UINavigationController può essere più facile da fare:

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

Il codice nella risposta sopra restituisce UINavigation controller (se ce l'hai) e se questo è ciò di cui hai bisogno, puoi usarlo self.navigationController.


5

A meno che tu non abbia una buona ragione, nel tuo controller di root fai questo:

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

E quando vuoi notificarlo:

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

2

Swift 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

1

Modo rapido per farlo, puoi chiamarlo da qualsiasi luogo, restituisce opzionale quindi fai attenzione a questo:

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

È inclusa come funzione standard in:

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3: Chage ViewController withOut Segue e invia AnyObject Use: Identity MainPageViewController su ViewController di destinazione

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

o se vuoi cambiare il controller di visualizzazione e inviare i dati

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)  

Sei il miglior ragazzo :)
bsm-2000
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.