objective c - para - Cómo identificar el controlador de vista anterior en la pila de navegación
instalar drivers manualmente windows 10 (17)
Acceda al elemento n-2
de la propiedad viewControllers
para acceder al controlador de vista principal.
Una vez que tenga esa instancia, puede verificar su tipo registrando lo que sale de la función NSStringFromClass()
. O bien, podría conservar una cadena de identificador de static const
en los controladores A y B, y una función getter que imprime la cadena.
Tengo 2 navigationcontrollers
separados, uno con RootViewController
A y el otro con RootViewController
B.
Puedo presionar ViewController
C en la pila de navegación A o B.
Pregunta: Cuando estoy en ViewController
C, ¿cómo puedo averiguar si estoy en la pila que pertenece a A o B?
Aquí está la implementación de la respuesta aceptada:
- (UIViewController *)backViewController
{
NSInteger numberOfViewControllers = self.navigationController.viewControllers.count;
if (numberOfViewControllers < 2)
return nil;
else
return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2];
}
Aquí hay una versión modificada del código Swift de Prabhu Beeman que lo adapta para admitir Swift 3:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for i in (1..<stack.count).reverse() {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
Como una extensión UINavigationController
:
extension UINavigationController {
func previousViewController() -> UIViewController? {
guard viewControllers.count > 1 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
Con Swift usando guardia.
extension UIViewController {
func getPreviousViewController() -> UIViewController? {
guard let _ = self.navigationController else {
return nil
}
guard let viewControllers = self.navigationController?.viewControllers else {
return nil
}
guard viewControllers.count >= 2 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
Encontrar el controlador de vista anterior es simple.
En su caso, es decir, usted está en C y necesita B, [self.navigationController.viewControllers lastObject]
es lo que quiere.
Para A, ya que A es el controlador de vista raíz, puede reemplazar lastObject
con firstObject
para obtener.
Implementación para Swift 2.2 - Agregue esto en una extensión UIViewController
. Seguro en el sentido de que devolverá nil
si viewcontroller es rootvc o no en un control de navegación.
var previousViewController: UIViewController? {
guard let viewControllers = navigationController?.viewControllers else {
return nil
}
var previous: UIViewController?
for vc in viewControllers{
if vc == self {
break
}
previous = vc
}
return previous
}
Implementación rápida del código @tjklemz:
var backViewController : UIViewController? {
var stack = self.navigationController!.viewControllers as Array
for (var i = stack.count-1 ; i > 0; --i) {
if (stack[i] as UIViewController == self) {
return stack[i-1] as? UIViewController
}
}
return nil
}
Implementación tjklemz código tjklemz como una extensión:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for(var i=stack.count-1;i>0;--i) {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
Mi extensión, veloz 3
extension UIViewController {
var previousViewController: UIViewController? {
guard let controllers = navigationController?.viewControllers, controllers.count > 1 else { return nil }
switch controllers.count {
case 2: return controllers.first
default: return controllers.dropLast(2).first
}
}
}
Porque los caballos muertos disfrutan de ser derrotados :)
- (UIViewController *)previousViewController
{
NSArray *vcStack = self.navigationController.viewControllers;
NSInteger selfIdx = [vcStack indexOfObject:self];
if (vcStack.count < 2 || selfIdx == NSNotFound) { return nil; }
return (UIViewController *)[vcStack objectAtIndex:selfIdx - 1];
}
Puede usar la propiedad viewControllers
:
@property(nonatomic, copy) NSArray *viewControllers
Discusión: El controlador de vista raíz está en el índice 0 en la matriz, el controlador de vista posterior en el índice n-2 y el controlador superior en el índice n-1, donde n es el número de elementos en la matriz.
https://developer.apple.com/documentation/uikit/uinavigationcontroller
Puede usar eso para probar si el controlador de vista raíz (el que está en el índice 0 de la matriz) es ver el controlador A o B.
Una impedancia Swift más sucinta:
extension UIViewController {
var previousViewController: UIViewController? {
guard let nav = self.navigationController,
let myIdx = nav.viewControllers.index(of: self) else {
return nil
}
return myIdx == 0 ? nil : nav.viewControllers[myIdx-1]
}
}
Una implementación más general de la respuesta aceptada:
- (UIViewController *)backViewController {
NSArray * stack = self.navigationController.viewControllers;
for (int i=stack.count-1; i > 0; --i)
if (stack[i] == self)
return stack[i-1];
return nil;
}
Esto devolverá el "controlador de vista posterior" correcto, independientemente de dónde esté la clase actual en la pila de navegación.
Use el método navigationController
para recuperarlo. Ver la documentación en el sitio de Apple .
navigationController Un padre o ancestro que es un controlador de navegación. (solo lectura)
@property (nonatomic, readonly, retain) UINavigationController * navigationController
Discusión Solo devuelve un controlador de navegación si el controlador de vista está en su pila. Esta propiedad es nula si no se puede encontrar un controlador de navegación.
Disponibilidad Disponible en iOS 2.0 y posterior.
para swift 3 puedes hacer esto:
var backtoViewController:UIViewController!
for viewController in (self.navigationController?.viewControllers)!.reversed() {
if viewController is NameOfMyDestinationViewController {
backtoViewController = viewController
}
}
self.navigationController!.popToViewController(backtoViewController, animated: true)
Solo necesita reemplazar "NameOfMyDestinationViewController" por viewController que desea devolver.
- (UIViewController *)backViewController
{
NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];
if ( myIndex != 0 && myIndex != NSNotFound ) {
return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
} else {
return nil;
}
}