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)