Descartar simultáneamente vistas de navegación de UIN y vistas modales de forma programática

He intentado algunas respuestas en este sitio, pero ninguno de ellos parece relacionarse con mi problema

Tengo una aplicación MasterDetail que tiene dos tipos de segues que estoy usando. Cuando presiona un botón en la vista de detalle, usa un segue de inserción y empuja otra vista de detalle sobre eso. En la nueva vista de detalle (la que acaba de ser presionada) hay un botón que llama a otra UIView (hoja de formulario) usando una transición modal.

Lo que trato de hacer es cuando el usuario selecciona una fila, aparece un UIAlertView mostrando un mensaje, mientras que al mismo tiempo (no tiene que ser al mismo tiempo) descarta el UIViewcontroller (modal) y vuelve desde Viewcontroller que se presionó. Básicamente, necesito poder descartar todos los controladores de vistas, uno modal y uno push (nav) para que la vista regrese a la pantalla principal original con la que empezaron.

Tengo el UIAlertView funcionando bien y puedo hacer que el controlador de vista modal descarte usando [self.dismissViewControllerAnimated:YES completion:nil]; pero no sé cómo descartar el siguiente Viewcontroller (que está en un controlador de navegación). Usando esto: [self.navigationController popToRootViewControllerAnimated:NO]; No funciona.

Aquí es donde quiero llamar a la función para eliminar todas las vistas:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlWithIDAndChallenge]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; UIAlertView *message = [[UIAlertView alloc] initWithTitle@"Started" message:@"The challenge has begun!" delegate:nil cancelButtonTitle:@"OK!" otherButtonTitles:nil]; [message show] //right here is where I would normally dismiss the modal VC //here is where I would like to dismiss all VC } 

Si lo desea, en los proyectos iOS 6.0 (y posteriores) puede usar un segue de desenrollado. Por ejemplo, puedes:

  1. En su controlador de vista de nivel superior (aquel para el que desea relajarse, no el controlador del que se va a relajar), escriba un método segue de desenrollado, en este caso llamado unwindToTopLevel (personalmente, lo encuentro útil si el cambio tiene algún Indicación sobre cuál es el destino del segue, por razones que serán evidentes cuando lleguemos al paso 3, a continuación):

     - (IBAction)unwindToTopLevel:(UIStoryboardSegue *)segue { NSLog(@"%s", __FUNCTION__); } 
  2. En la escena de Interface Builder desde la que iniciará el desenrollado, controle ⌘ -drag desde el ícono del controlador de vista al ícono de salida para crear el segue de desenrollado:

    enter image description here

    En general, debe definir la transición de un botón a la salida (y listo), pero si desea invocar el cambio programáticamente, es posible que desee crearlo entre el controlador y la salida de desenrollado, como se muestra arriba.

  3. Obtendrás una pequeña ventana emergente que incluye el nombre de tus secuencias de desenrollado (de los controladores de presentación … es como magia):

    enter image description here

  4. Si vas a invocar ese cambio programáticamente, debes seleccionar ese desenlace en el contorno del documento en el lado izquierdo de la ventana del IB y, una vez que lo hayas hecho, puedes darle la posibilidad de desenrollar una ID del guión gráfico:

    enter image description here

    Generalmente uso el nombre del segue de desenrollado para la identificación del guión gráfico, pero puedes usar lo que quieras.

  5. Ahora, una vez hecho esto, su vista de alerta puede invocar el cambio:

     - (IBAction)didTouchUpInsideButton:(id)sender { [[[UIAlertView alloc] initWithTitle:nil message:@"go home" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil] show]; } #pragma mark - UIAlertViewDelegate - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex != [alertView cancelButtonIndex]) { [self performSegueWithIdentifier:@"unwindToTopLevel" sender:self]; } } 

Desde la clase presentaste tu vista modal

call dismiss de modal y luego realizar el selector después de un retraso y luego hacer el

Aquí está el código de ejemplo

 //Write this in the class from where you presented a modal View. //Call the function from modal class when you want to dismiss and go to root. - (void) dismissAndGoToRoot { [self dismissViewControllerAnimated:YES completion:nil]; [self performSelector:@selector(gotoRoot) withObject:nil afterDelay:0.50]; } - (void)gotoRoot { [self.navigationController popToRootViewControllerAnimated:NO]; } 

Aquí llamarás a la función

// aquí es donde normalmente descartaría el VC modal // aquí es donde me gustaría despedir a todos los VC

 [self.parentViewController dismissAndGoToRoot]; 

Si esto no funciona, tome una variable de instancia de ParentViewController en la clase modal y asigne al presentar el controlador de vista modal.

Podría intentar reemplazar [self.dismissViewControllerAnimated:YES completion:nil]; con

 self dismissViewControllerAnimated:YES completion:^{ [parentViewController.navigationController popToRootViewControllerAnimated:YES]; } 

Creo que parentViewController apuntará al controlador de vista que se está presentando, y el bloque hará que el controlador de navegación del controlador de vista principal se muestre en el controlador de vista raíz.