2010-07-11 11 views
32

Tengo 2 controladores de vista presentados de manera modal.Cómo descartar 2 controladores de vista modal en sucesión?

A presents B which presents C. 

Cuando descarto C, me gustaría despedir a B también. Pero no estoy seguro de cómo hacer esto:

Descartar C:

[self dismissModalViewControllerAnimated:YES] 
//[delegate dismissB] //this doesn't work either when i create a delegate pattern 

Ahora me quedo con B. ¿Cómo puedo despedir B de C?

Respuesta

9

intente utilizar el siguiente código en B (a la derecha después de despedir C, como ya lo hacen):

[self.parentViewController dismissModalViewControllerAnimated:YES]; 

IMPORTANTE:
No hacer nada en el método después de esta línea.
Este controlador de vista (B), probablemente se dará a conocer y desasignado ...

ACTUALIZACIÓN:
A partir de iOS7 el método anterior está en desuso.
Utilice el siguiente método en su lugar:

[self.parentViewController dismissViewControllerAnimated:YES completion:^{ /* do something when the animation is completed */ }]; 
+2

Probé esto, pero simplemente desestima C. B es aún visible. –

+3

Intenta descartar C sin animación y luego descarta B con animación ... Por cierto, ¿dónde está ubicado este código de descarte (qué clase y cómo se llama este método)? –

+0

El código de descarte está ubicado en C en un método llamado dismissAll. Se activa presionando un UIBarButtonItem. –

0

El controlador de navegación tiene una propiedad "viewControllers" que es una matriz - se puede establecer que a una nueva matriz menos los dos controladores de vista que desea eliminar.

+0

No estoy seguro si te entiendo. puedes actualizar w/code? –

12

En B. Ponga:

[self dismissModalViewControllerAnimated:NO]; 
[self dismissModalViewControllerAnimated:YES]; 

Sólo ejecutar una animación.

2

Solo necesita un comando de descartar. Solo descarte B, y luego C se irá con eso.

+1

este enfoque parece estar funcionando muy bien. ¿Alguien por ahí ve las desventajas de este enfoque? – kris

103

acabo de enterar que es necesario utilizar presentingViewController en IOS 5.

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; 

A -> B -> C

Ejecutar el código anterior en C modal le llevará de vuelta a A

+2

¡GRACIAS! He estado buscando durante horas para encontrar esto :-) – Tony

+0

No hay problema :-) Cada ejemplo que encontré fue para iOS5 anterior y nunca funcionó – Andy

+0

Exactamente mi problema. – Tony

0

Inspirado por la solución Albertos, creé un método de delegado en B con un bloque para mostrar el resultado de eliminar una cuenta:

#pragma - mark - AddAccountViewControllerDelegate Methods 

- (void) dismissToSettings { 
    [self dismissModalViewControllerAnimated:NO]; 
    [self dismissViewControllerAnimated:YES completion:^(void){[DKMessage showMessage:LS(@"Account was successfully created")];}]; 
} 
0

que enfrentan el mismo problema, y ​​una mejor solución fue la creación de un "DismissViewProtocol" de la siguiente manera:

del archivo: DismissViewProtocol.h

@protocol DismissViewProtocol <NSObject> 
-(void)dismissView:(id)sender; 
@end 

En mi opinión B-modal, de dejar que la respuesta para el método delegado :

en mi archivo BH:

#import "DismissViewProtocol.h" 
@interface B-Modal : UIViewController <DismissViewProtocol> 
... 
@end 

en mi b.m archivo:

-(void) dismissView:(id)sender 
{ 
[((UIViewController *) sender) dismissModalViewControllerAnimated:NO]; 
[self dismissModalViewControllerAnimated:YES]; 
} 

En el mismo controlador B-view, cuando llamo al A continuación, en mi punto de vista modal B, cuando llamo a la otra vista modal C, suponiendo que para segue:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    ((C-ViewController *)segue.destinationViewController).viewDelegate=self; 
} 

por último, en mi archivo ch, vamos a preparar para el delegado:

@property(nonatomic, weak) id <DismissViewProtocol> viewDelegate; 

y en mi archivo cm, acabo de decirle a mi viewDelegate para despedir mi controlador de vista modal y en sí:

-(void)closeBothViewControls 
{ 
     [self.viewDelegate dismissView:self]; 
} 

Y eso es todo.

Espero que funcione para todos ustedes.

2

Esto funcionó para mí:

// Swift 
presentingViewController?.dismissViewControllerAnimated(true, completion: nil) 

// Objective-C 
[self.presentingViewController dismissViewControllerAnimated:true completion:nil] 
+1

Los argumentos de mensajería en Objective-C no son separados por coma, por lo que estará sin coma después de "verdadero" para // Objective-C [self.presentingViewController dismissViewControllerAnimated: true completion: nil] –

+0

B no se descarta cuando agrego el código y actualice su objetivo c sintaxis tambien eliminar la coma después de verdadero. –

3

Comprobar esto para esperar:

self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil); 
2

He leído todos los temas y no he encontrado una respuesta adecuada. Si descarta B, C desaparecerá inmediatamente y creará un efecto extraño. La forma correcta es presentar C como un controlador de vista infantil con animación personalizada desde el fondo, como:

[b addChildViewController:c]; 
    c.view.frame = CGRectOffset(b.view.bounds, 0, b.view.bounds.size.height); 
    [b.view addSubview:c.view]; 
    [c didMoveToParentViewController:b]; 

    [UIView animateWithDuration:0.5 animations:^{ 
     c.view.frame = CGRectOffset(c.view.frame, 0, -b.view.bounds.size.height); 
    } completion:^(BOOL finished) { 

    }]; 

Y entonces simplemente descartar B y todo se ve mucho mejor!

13

Esto funcionó para mí, muy simple

// Call inside View controller C  
self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil) 
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil) 

Explicación:

Si se llama a descartar en C, sólo se puede quitar C. Si se llama despido a B, que va a hacer lo correcto : Retire el controlador de vista modal más arriba. La primera llamada, por lo tanto, elimina C (sin animación). La segunda llamada elimina B.

La manera más fácil de acceder al controlador de vista B desde C es utilizar la variable presentingViewController.

+0

esto funcionó como un encanto .. – aznelite89

0

Aquí es una manera de cómo despedir controlador de vista más que uno modal usando ciclo de repetición:

Swift 3

// In this example code will go throw all presenting view controllers and 
// when finds it then dismisses all modals. 
var splitViewController: UIViewController? = self 

repeat { 
    splitViewController = splitViewController?.presentingViewController 
} while (!(splitViewController is UISplitViewController) && (splitViewController != nil)) 

splitViewController?.dismiss(animated: true, completion: nil) 
Cuestiones relacionadas