29

¿es posible sacar una vista de la pila de navegación y luego presionar otra directamente sobre ella?apareciendo y empujando los controladores de vista en la misma acción

Estoy tratando de implementar una jerarquía plana para esta sección y me gustaría tener un controlador segmentado pero no puedo hacer que el controlador segmentado se vea como yo quiera, por lo tanto, estoy tratando de usar el controlador de navegación .

Cuando se hace clic en un botón que ejecuta este código:

[[self navigationController] popViewControllerAnimated:YES]; 
     MapsViewController *aViewController = [[MapsViewController alloc] 
               initWithNibName:@"MapsViewController" bundle:nil]; 
[self.navigationController pushViewController:aViewController animated:NO]; 
[aViewController release]; 

Está apareciendo fuera bien, pero theres ninguna señal de empujar! Cualquier ayuda sería apreciada.

Respuesta

38
MapsViewController *aViewController = [[MapsViewController alloc] 
             initWithNibName:@"MapsViewController" bundle:nil]; 
    // locally store the navigation controller since 
    // self.navigationController will be nil once we are popped 
UINavigationController *navController = self.navigationController; 

    // retain ourselves so that the controller will still exist once it's popped off 
[[self retain] autorelease]; 

    // Pop this controller and replace with another 
[navController popViewControllerAnimated:NO];//not to see pop 

[navController pushViewController:aViewController animated:YES];//to see push or u can change it to not to see. 

O

MapsViewController *aViewController = [[MapsViewController alloc] 
             initWithNibName:@"MapsViewController" bundle:nil]; 


UINavigationController *navController = self.navigationController; 

//Get all view controllers in navigation controller currently 
NSMutableArray *controllers=[[NSMutableArray alloc] initWithArray:navController.viewControllers] ; 

//Remove the last view controller 
[controllers removeLastObject]; 

//set the new set of view controllers 
[navController setViewControllers:controllers]; 

//Push a new view controller 
[navController pushViewController:aViewController animated:YES]; 
+0

No es solo que no puedo ver el impulso que está sucediendo, no está sucediendo. Al menos no hay evidencia de que haya sucedido. – Josh

+0

Es una instancia de MapViewController – Josh

+0

He actualizado mi código simplemente péguelo y ejecute –

26

Tomado de solución https://stackoverflow.com/users/1619554/tomer-peled 's, para que otros usuarios puedan encontrar más fácilmente.

Ésta parece ser la mejor manera de hacerlo por iOS8:

UIViewController *newVC = [[UIViewController alloc] init]; // Replace the current view controller 
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]]; 
[viewControllers removeLastObject]; 
[viewControllers addObject:newVC]; 
[[self navigationController] setViewControllers:viewControllers animated:YES]; 
+1

Esta solución funcionó para mí con iOS 8 y no con la respuesta seleccionada. ¡Gracias! – thefoyer

12

En Swift:

let newVc = UIViewController() 
var vcArray = self.navigationController?.viewControllers 
vcArray!.removeLast() 
vcArray!.append(newVc) 
self.navigationController?.setViewControllers(vcArray!, animated: false) 

En caso newVc existe en un Storyboard:

let storyboard = UIStoryboard(name: "Main", bundle: nil) 
let newVc = storyboard.instantiateViewControllerWithIdentifier("YourViewControllerIdentifier") as! UIViewController 
var vcArray = self.navigationController?.viewControllers 
vcArray!.removeLast() 
vcArray!.append(newVc) 
self.navigationController?.setViewControllers(vcArray!, animated: false) 
+0

Rodrigo, salvou meu dia. vlw! –

+0

Gracias, salvó mi día :) –

4

Usted puede usar este código para abrir o empujar su controlador.

Para objetivo c

bool alreadyPushed = false;  
//Check if the view was already pushed 
NSMutableArray *viewControllers; 
if ((viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers])) { 

    for (UIViewController *aViewController in viewControllers) { 

     if ([aViewController isKindOfClass:[YourControllerName class]]) { 
      NSLog(@"pop your view controller"); 
      [self.navigationController popToViewController:aViewController animated:YES]; 
      alreadyPushed = true; 
      break; 
     } 
    } 
} 

//Push Fresh View 
if(alreadyPushed == false) { 

    NSLog(@"push your view controller"); 
    YourControllerName *YourControllerObject = [[YourControllerName alloc]initWithNibName:@"YourNibName" bundle:nil];   
    [self.navigationController pushViewController:YourControllerObject animated:YES]; 

} 

Para Swift

var alreadyPushed = false    
     //Check if the view was already pushed 
     if let viewControllers = self.navigationController?.viewControllers { 
      for viewController in viewControllers {      
       if let viewController = viewController as? YourControllerName {            
        self.navigationController?.popToViewController(viewController, animated: true);       
        print(" Push Your Controller") 
        alreadyPushed = true 
        break       
       } 
      } 
     }       
     if alreadyPushed == false {     
      let YourControllerObject = self.storyboard?.instantiateViewControllerWithIdentifier("YourControllerIdentifire") as! YourControllerName    
      self.navigationController?.pushViewController(YourControllerObject, animated: true) 

     } 
0
BOOL Present = NO; 

fifthViewController * fifthVC = [self.storyboard instantiateViewControllerWithIdentifier:@"homeController"]; 


for (UIViewController* viewController in self.navigationController.viewControllers) { 

    //This if condition checks whether the viewController's class is MyGroupViewController 
    // if true that means its the MyGroupViewController (which has been pushed at some point) 
    if ([viewController isKindOfClass:[fifthViewController class]]) 
    { 

     // Here viewController is a reference of UIViewController base class of MyGroupViewController 
     // but viewController holds MyGroupViewController object so we can type cast it here 
     fifthViewController *groupViewController = (fifthViewController*)viewController; 
     [self.navigationController popToViewController:groupViewController animated:NO]; 
     Present=YES; 
    } 

} 

if(Present==NO) 
{ 
    [self PushAnimation]; 
    [self.navigationController pushViewController:fifthVC animated:NO]; 

    Present=YES; 
} 
0

Swift 3,0

En caso de que alguien quiere g o profundamente en la vista de jerarquía:

   //Go back to desired viewController and then push another viewController 
       var viewControllers = self.navigationController!.viewControllers 
       while !(viewControllers.last is MyViewControllerClass) { 
        viewControllers.removeLast() 
       } 
       // go to new viewController 
       let anotherViewController = AnotherViewController(nibName: "AnotherViewController", bundle: nil) 
       viewControllers.append(anotherViewController) 
       self.navigationController?.setViewControllers(viewControllers, animated: true) 
1

Swift 4:

self.navigationController.setViewControllers[].. no significa funcionó para mí. Pero puedo resolver el problema manteniendo un controlador de navegación en una variable de instancia y hacer una operación push/pop. Por lo tanto, silenciosamente capaz de cambiar el controlador sin falla.

let navigationVC = self.navigationController 
    navigationVC?.popViewController(animated: false) 
    navigationVC?.pushViewController(myNewVC, animated: false) 
Cuestiones relacionadas