bar iphone uinavigationcontroller

iphone - uinavigationbar ios



¿Cómo obtengo el RootViewController desde un controlador empujado? (7)

Entonces, presiono un controlador de vista desde RootViewController como:

[self.navigationController pushViewController:anotherViewController animated:YES] ;

PERO, desde otro anotherViewController ahora, quiero acceder al RootViewController nuevamente.

Lo estoy intentando

// (inside anotherViewController now) ///RootViewController *root = (RootViewController*)self.parentViewController ; // No. // err RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works

No estoy seguro de por qué funciona esto y no estoy seguro de si es la mejor manera de hacerlo. ¿Alguien puede comentar sobre una mejor manera de obtener RootViewController de un controlador que ha introducido en el control de navegación de RootViewController y si la forma en que lo he hecho es confiable o no?



Aquí se me ocurrió el método universal para navegar desde cualquier lugar hasta la raíz.

  1. Usted crea un nuevo archivo de clase con esta clase, para que sea accesible desde cualquier lugar de su proyecto:

    import UIKit class SharedControllers { static func navigateToRoot(viewController: UIViewController) { var nc = viewController.navigationController // If this is a normal view with NavigationController, then we just pop to root. if nc != nil { nc?.popToRootViewControllerAnimated(true) return } // Most likely we are in Modal view, so we will need to search for a view with NavigationController. let vc = viewController.presentingViewController if nc == nil { nc = viewController.presentingViewController?.navigationController } if nc == nil { nc = viewController.parentViewController?.navigationController } if vc is UINavigationController && nc == nil { nc = vc as? UINavigationController } if nc != nil { viewController.dismissViewControllerAnimated(false, completion: { nc?.popToRootViewControllerAnimated(true) }) } } }

  2. Uso desde cualquier lugar de su proyecto:

    { ... SharedControllers.navigateToRoot(self) ... }


Como una adición a @dulgan''s respuesta de @dulgan''s , siempre es un buen enfoque usar firstObject sobre objectAtIndex:0 , porque mientras que el primero devuelve nil si no hay ningún objeto en el array, este último lanza una excepción.

UIViewController *rootViewController = self.navigationController.viewControllers.firstObject;

Alternativamente, sería una gran ventaja para ti crear una categoría llamada UINavigationController+Additions y definir tu método en eso.

@interface UINavigationController (Additions) - (UIViewController *)rootViewController; @end @implementation UINavigationController (Additions) - (UIViewController *)rootViewController { return self.viewControllers.firstObject; } @end


Para todos los interesados ​​en una extensión rápida, esto es lo que estoy usando ahora:

extension UINavigationController { var rootViewController : UIViewController? { return self.viewControllers.first as? UIViewController } }


Una versión ligeramente menos fea de lo mismo mencionado en casi todas estas respuestas:

UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];

en tu caso, probablemente haga algo como:

dentro de su subclase UINavigationController :

- (UIViewController *)rootViewController { return [[self viewControllers] firstObject]; }

entonces puedes usar:

UIViewController *rootViewController = [self.navigationController rootViewController];

editar

OP pidió una propiedad en los comentarios.

si lo desea, puede acceder a esto a través de algo como self.navigationController.rootViewController simplemente agregando una propiedad de solo lectura a su encabezado:

@property (nonatomic, readonly, weak) UIViewController *rootViewController;


Use la propiedad viewControllers del UINavigationController. Código de ejemplo:

// Inside another ViewController NSArray *viewControllers = self.navigationController.viewControllers; UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];

Esta es la forma estándar de obtener el controlador de vista "hacia atrás". La razón por la que objectAtIndex:0 funciona es porque el controlador de vista al que está intentando acceder también es el de la raíz; si profundiza en la navegación, la vista posterior no sería la misma que la vista raíz.


Versión Swift:

var rootViewController = self.navigationController?.viewControllers.first

Versión de ObjectiveC:

UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];

Donde self es una instancia de un UIViewController incrustado en un UINavigationController.