Come eliminare 2 controller di visualizzazione modale in successione?

Ho 2 controller di vista presentati modalmente.

A presents B which presents C. 

Quando licenzio l’IC, vorrei liquidare anche B. Ma non sono sicuro di come farlo:

Elimina C:

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

Ora sono rimasto con B. Come posso licenziare B da C?

Prova a usare il prossimo codice in B (subito dopo aver chiuso C, come già fai):

 [self.parentViewController dismissModalViewControllerAnimated:YES]; 

IMPORTANTE :
Non fare nulla nel metodo dopo questa linea.
Questo controller di visualizzazione (B) verrà probabilmente rilasciato e deallocato …

AGGIORNAMENTO :
A partire da iOS7 il metodo sopra è deprecato.
Utilizza invece il metodo successivo:

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

Appena scoperto, è necessario utilizzare PresentationViewController in iOS 5.

 [self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; 

A -> B -> C

Eseguendo il codice sopra nel modale C tornerai su A

Questo ha funzionato per me, molto semplice

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

Spiegazione:

Se chiami il licenziamento su C, può rimuovere solo C. Se chiami il licenziamento su B, farà la cosa giusta: rimuovi il controller di visualizzazione modale più in alto. La prima chiamata rimuove quindi C (senza animazione). La seconda chiamata rimuove B.

Il modo più semplice per accedere al controller di visualizzazione B da C è utilizzare la variabile presentandoViewController.

In B. Metti:

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

Esegui solo un’animazione.

Controlla questo per swift:

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

Hai solo bisogno di un comando di rimozione. Basta congedare B, e poi C andrà via con esso.

Ho letto tutti gli argomenti e non ho trovato una risposta adeguata. Se si elimina B, C sparirà immediatamente e creerà un effetto strano. Il modo corretto è di presentare C come un controller di visualizzazione figlio con animazione personalizzata dal basso, come:

  [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) { }]; 

E poi basta congedare B e sembra tutto molto più bello!

Questo ha funzionato per me:

 // Swift presentingViewController?.dismissViewControllerAnimated(true, completion: nil) // Objective-C [self.presentingViewController dismissViewControllerAnimated:true completion:nil]; 

In swift 4

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil);

Il controller di navigazione ha una proprietà “viewControllers” che è una matrice: è ansible impostarla su una nuova matrice meno i due controller di vista che si desidera rimuovere.

Ispirato alla soluzione Albertos, ho creato un metodo delegato in B con un blocco per mostrare il risultato dell’eliminazione di un account:

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

Ho affrontato lo stesso problema e una soluzione migliore era la creazione di un “DismissViewProtocol” come segue:

File: DismissViewProtocol.h

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

Nella mia vista modale B, rispondiamo per il metodo delegato:

nel mio file bh:

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

nel mio file bm:

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

Nello stesso controller B-view, quando chiamo Next, nella mia vista modale B, quando chiamo l’altra vista modale C, supponendo che per segue:

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

Infine, nel mio file ch, prepariamo il delegato:

 @property(nonatomic, weak) id  viewDelegate; 

E nel mio file cm, dico al mio viewDelegate di chiudere il mio controller di visualizzazione modale e se stesso:

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

E questo è tutto.

Spero che funzioni per tutti voi.

Ecco un modo per eliminare più di un controller di visualizzazione modale utilizzando il ciclo di ripetizione:

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)