2012-04-04 17 views
45

Tengo una vista en un guión gráfico que tiene un botón para realizar una determinada acción. Sin embargo, para realizar esta acción, el usuario debe haber iniciado sesión. El manejador de botones prueba si el usuario está conectado y realiza una transición si es SÍ y otra si NO. El NO segues empuja a un controlador de vista de inicio de sesión. Hay otra transición que se conecta de nuevo al controlador de la primera vista, por lo que si el inicio de sesión es exitoso, el usuario puede continuar desde donde lo dejó. Los controladores de vista están integrados en un controlador de navegación.¿Cómo volver a un UIViewController que ya está cargado?

El problema es que el segue 'de retorno' carga una instancia completamente nueva del controlador de vista y no hace referencia a la instancia original, así que termino con elementos de interfaz vacíos y 2 copias de ese controlador de vista en la memoria.

¿Cómo puedo volver a la instancia original del controlador de vista?

Respuesta

135

Suponiendo que utiliza "push", quiere decir que está utilizando un UINavigationController, luego puede usar lo siguiente para volver al principio de la pila.

[self.navigationController popToRootViewControllerAnimated:YES]; 

o

UIViewController *prevVC = [self.navigationController.viewControllers objectAtIndex:<n>]; 
[self.navigationController popToViewController:prevVC animated:YES]; 

a pop a un nivel específico en el que <n> es el nivel.

o

[self.navigationController popViewControllerAnimated:YES]; 

Si lo que desea es hacer estallar un nivel anterior a la pila de navegación.

+1

Tengo un UIBarButton que se carga inicialmente en ViewDidLoad en la pantalla anterior (al que vamos a volver). Cuando uso tu código, UIBar no se muestra en absoluto. ¿Alguna idea de por qué? – c0d3Junk13

33

En lugar de usar un segue para volver al controlador anterior, debe usar el evento que estaba asociado con el cambio regresando para descartar el controlador de vista actual (si fue modal) o extraerlo del controlador de navegación (si el segue fue push) y el controlador anterior se mostrará automáticamente.

Por ejemplo, si el cambio modal que se realizaba hacia atrás se realizaba al presionar un botón en su pantalla de inicio de sesión, elimina la transición del guión gráfico y el evento retoque dentro del botón que vincula con su acción que , después de autenticarse satisfactoriamente llamará:

[self dismissViewControllerAnimated:YES completion:nil]; 

en el guión gráfico, que va a la derecha haga clic en el botón y arrastre el retoque evento dentro enviado al primer nivel de respuesta de la escena controlador de vista. Esto ejecutará la transición inversa que se ejecutó cuando realizó la transición de segue. Puede usar una transición modal para eso, sin necesidad de usar un controlador de navegación.

Si presionó la vista de inicio de sesión en el controlador de navegación, debe sacarlo de la pila (si vuelve a la vista anterior). Utilice uno de los siguientes:

[[self navigationController] popViewControllerAnimated:YES]; // goes back to previous view 
[[self navigationController] popToViewController: myViewControllerAfterLogin animated:YES]; // goes back to specific view on stack. 
[[self navigationController] popToRootViewControllerAnimated:YES]; // goes back to first view on the stack 

La transición animada debería invertir el tipo de transición utilizado en la segue, por lo enroscarse será curvado hacia abajo cuando se oponen a la visión.

+0

Si usa un segue personalizado, como un efecto de no deslizamiento para un segue de inserción, el pop no será el inverso de su transición personalizada, sino simplemente un efecto de diapositiva. – nenchev

2

malhal es correcto - que vale la pena hacer clic en su enlace.

Parece que el código se movió un poco del ejemplo de Apple y es aún más flexible. Tengo tres escenas pero solo un archivo ViewController .m personalizado. No quería una pila de navegación. El acceso a las escenas subsiguientes se realiza mediante segues de botones. He añadido esta línea en el archivo de controlador de vista base .m:

- (IBAction)unwindForSegue:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC{} 

Luego, en la tercera escena controlo arrastrado desde un botón hasta el icono de salida y seleccionado la acción de desenrollado. Ahora regresa de la escena 3 de vuelta a la escena 2 sin necesidad de llamar a un método de descartar ViewController.

+0

Creo que la clave que finalmente entendí es que va a desenrollar su pila hasta que llegue a un controlador que implemente la acción de desenrollado asociada con la transición de salida específica que está utilizando. De modo que puede definir múltiples segmentos de salida con diferentes acciones de desenrollado, y luego implementar la acción de desenrollamiento específica en el controlador donde desea aterrizar, para cada uno de los segmentos. –

Cuestiones relacionadas