2010-03-10 10 views

Respuesta

52

Se puede crear una variedad de NSMutableArray de viewcontrollers del navigationController e insertar nuevos viewController antes del actual. Luego configure la matriz viewControllers sin animación y vuelva a abrir.

UIViewController *newVC = ...; 
NSMutableArray *vcs = [NSMutableArray arrayWithArray:self.navigationController.viewControllers]; 
[vcs insertObject:newVC atIndex:[vcs count]-1]; 
[self.navigationController setViewControllers:vcs animated:NO]; 
[self.navigationController popViewControllerAnimated:YES]; 
+0

Interesante enfoque. Podría funcionar, aunque es probable que venga con algunos arañazos. –

+0

sonido algo interesante. Necesito pasar algunas informaciones dentro del ViewController para que tal vez funcione de esta manera. ¿Puede mostrarme cómo puedo insertar mi nuevo ViewController antes que el actual? – ludo

+1

He agregado un fragmento de código, que ilustra este enfoque. Esto definitivamente no está en línea con el HIG y probablemente confundirá a los usuarios. Pero debería hacer lo que solicitó. Aunque no probé eso. – FelixLam

2

No, de derecha a izquierda se reserva para hacer estallar viewcontrollers de la pila de navegación. Sin embargo, puede obtener ese efecto animando las vistas usted mismo. Algo como:

[UIView beginAnimations:@"rightToLeft" context:NULL]; 
CGRect newFrame = aView.frame; 
newFrame.origin.x -= newFrame.size.width; 
aView.frame = newFrame; 
[UIView commitAnimations]; 

Sin embargo, esto no le hará nada a su controlador de navegación.

+0

bueno saber y cómo hacerlo si aparece la vista desde la pila de navegación? – ludo

+0

@Ludo: no se pueden mostrar vistas desde la pila de navegación. la "pila" contiene viewcontrollers – FelixLam

+0

Lo siento, mi mal. Escribí las vistas, pero, por supuesto, tenía los controladores de vista en mente. Cómo explotar un controlador de visualización se explica con las otras respuestas. –

2

Parece que desea "volver atrás". Esto puede lograrse mediante tres métodos en su UINavigationController ejemplo:

para volver a la "raíz" del controlador:

-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated

O para volver a uno de los controladores anteriores:

-(NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated

O para volver al controlador previamente empujado:

-(UIViewController *)popViewControllerAnimated:(BOOL)animated

+0

gracias por ayudar, solo quiero probar la respuesta de Félix pero realmente no sé cómo hacerlo – ludo

36

Por favor, intente éste

HomePageController *pageView = [[HomePageController alloc] initWithNibName:@"HomePageController_iPhone" bundle:nil]; 

CATransition *transition = [CATransition animation]; 
transition.duration = 0.45; 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; 
transition.type = kCATransitionPush; 
transition.subtype = kCATransitionFromLeft; 
transition.delegate = self; 
[self.navigationController.view.layer addAnimation:transition forKey:nil]; 

self.navigationController.navigationBarHidden = NO; 
[self.navigationController pushViewController:pageView animated:NO]; 
+0

+1 - Ejemplo perfecto y explicación. – Dhruv

+1

+1 funciona muy bien – iLearner

+1

¿por qué establece el tipo de transición dos veces? – Yarneo

6

Este código está trabajando muy bien. Por favor, intente

CATransition *transition = [CATransition animation]; 
transition.duration = 0.3f; 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
transition.type = kCATransitionReveal; 
[self.navigationController.view.layer addAnimation:transition forKey:nil]; 
[self.navigationController pushViewController:phoneServicesViewController animated:NO]; 
+0

¡Finalmente! Lo he intentado durante horas y ninguno ha funcionado hasta el tuyo. –

+0

@TriannaBrannon me alegra saber que los fragmentos de código fueron útiles para usted. –

9
Try this : 
//Push effect in reverse way 
    CATransition* transition = [CATransition animation]; 
    transition.duration = 0.75; 
    transition.type = kCATransitionPush; 
    transition.subtype = kCATransitionFromLeft; 
    [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; 
    [self.navigationController pushViewController:vc animated:NO]; 
+0

debe aceptarse respuesta –

0

que tenía el mismo problema, esto es cómo lo resolví

[self.navigationController popViewControllerAnimated: YES];

Esto se parecerá a "volver" es decir, una situación en la que se hace clic en un botón de retroceso y navegar a la página anterior

1

Sólo una mejora de la mejor respuesta aquí en mi opinión:

UIViewController *newVC = ...; 
[self.navigationController setViewControllers:@[newVC, self] animated:NO]; 
[self.navigationController popViewControllerAnimated:YES]; 

Y para volver al controlador inicial, simplemente presiona.

0

Basado en la respuesta de @felixlam, actualicé y creé un controlador de navegación en dirección "inversa" que anula los métodos push/pop predeterminados para actuar de esta manera.

class LeftPushNavigationController: BaseNavigationController { 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    interactivePopGestureRecognizer?.isEnabled = false 
    } 

    override func pushViewController(_ viewController: UIViewController, animated: Bool) { 
    // If the push is not animated, simply pass to parent 
    guard animated else { return super.pushViewController(viewController, animated: animated) } 

    // Setup back button 
    do { 
     // Hide original back button 
     viewController.navigationItem.setHidesBackButton(true, animated: false) 
     // Add new one 
     viewController.navigationItem.rightBarButtonItem = UIBarButtonItem(
     image: #imageLiteral(resourceName: "iconBackReverse"), 
     style: .plain, 
     target: self, 
     action: #selector(self.pop) 
    ) 
    } 

    // Calculate final order 
    let finalVCs = self.viewControllers + [viewController] 

    // Insert the viewController to the before-last position (so it can be popped to) 
    var viewControllers = self.viewControllers 
    viewControllers.insert(viewController, at: viewControllers.count - 1) 

    // Insert viewcontroller before the last one without animation 
    super.setViewControllers(viewControllers, animated: false) 
    // Pop with the animation 
    super.popViewController(animated: animated) 
    // Set the right order without animation 
    super.setViewControllers(finalVCs, animated: false) 
    } 

    override func popViewController(animated: Bool) -> UIViewController? { 
    // If the push is not animated, simply pass to parent 
    guard animated else { return super.popViewController(animated: animated) } 

    guard self.viewControllers.count > 1 else { return nil } 

    // Calculate final order 
    var finalVCs = self.viewControllers 
    let viewController = finalVCs.removeLast() 

    // Remove the parent ViewController (so it can be pushed) 
    var viewControllers = self.viewControllers 
    let parentVC = viewControllers.remove(at: viewControllers.count - 2) 

    // Set the viewcontrollers without the parent & without animation 
    super.setViewControllers(viewControllers, animated: false) 
    // Create push animation with the parent 
    super.pushViewController(parentVC, animated: animated) 
    // Set the right final order without animation 
    super.setViewControllers(finalVCs, animated: false) 

    // Return removed viewController 
    return viewController 
    } 

    @objc 
    private func pop() { 
    _ = popViewController(animated: true) 
    } 

} 
Cuestiones relacionadas