¿Cómo obtener el controlador de vista raíz?


109

Necesito una instancia del controlador de vista raíz.

Probé esos enfoques:

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

Devoluciones: nulo :

Además, cuando trato de obtener una matriz de controladores:

NSArray *viewControllers = self.navigationController.viewControllers;

Devuelve solo un controlador, pero no es mi controlador de vista raíz.

Si trato de tomar del controlador de navegación:

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

Devoluciones: nulo :

¿Alguna idea de por qué? ¿Qué más puedo intentar para obtener una instancia de mi controlador de vista raíz?

Gracias.


KeyWindow es la ventana activa, por ejemplo, cuando muestra un UIAlertView, la ventana de UIAlertView es keyWindow pero no es la ventana de AppDelegate. Si desea obtener el rootViewController de la aplicación, tal vez use [[[UIApplication sharedApplication] delegate] window] rootViewController ] es mejor.
无 夜 之 星辰

Respuestas:


213

si está intentando acceder al rootViewControllerque configuró en su appDelegate. prueba esto:

C objetivo

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

Rápido

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 y 4.2

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

Swift 5 y 5.1 y 5.2

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

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

1
En Swift2, tienes que usar "let appDelegate = UIApplication.sharedApplication (). Delegate as! AppDelegate", para forzar el desenvolvimiento
Jacky

¿Hay alguna forma de tener dos controladores asignados de esta manera para que pueda extraer datos de ambos al reloj?
Johnny Marin

1
Este es un salvavidas. ¡Gracias! ¡Me tomó meses encontrar este delicioso código!
ItsMeDom

37

C objetivo

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

Swift 2.0

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

Rápido 5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
Esta debería ser la mejor respuesta. +1 Las otras respuestas no funcionarán si necesita hacer referencia al controlador de vista raíz desde un marco diferente del que depende su aplicación principal.
C. Tewalt

10

Como lo sugiere aquí @ 0x7fffffff, si tiene UINavigationController, puede ser más fácil de hacer:

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

El código en la respuesta anterior devuelve el controlador UINavigation (si lo tiene) y si esto es lo que necesita, puede usarlo self.navigationController.


5

A menos que tenga una buena razón, en su controlador raíz haga esto:

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

Y cuando quieras notificarlo:

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

2

Swift 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

1

Una forma rápida de hacerlo, puede llamar a esto desde cualquier lugar, devuelve opcional, así que tenga cuidado con eso:

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

Se incluye como función estándar en:

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3: Chage ViewController con Out Segue y envía AnyObject Use: Identity MainPageViewController en el ViewController de destino

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

o si desea cambiar el controlador de vista y enviar datos

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)  

Eres el mejor amigo :)
bsm-2000
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.