Como Descartar 2 Controladores de Visualização Modal em Sucessão?

Eu tenho 2 view controllers apresentados modalmente.

A presents B which presents C. 

Quando eu dispensar CI gostaria de descartar B também. Mas não tenho certeza de como fazer isso:

Dispensar C:

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

Agora estou com B. Como posso demitir B de C?

Tente usar o próximo código em B (logo depois de dispensar C, como você já faz):

 [self.parentViewController dismissModalViewControllerAnimated:YES]; 

IMPORTANTE :
Não faça nada no método após esta linha.
Este view controller (B) provavelmente será liberado e desalocado …

ATUALIZAÇÃO :
A partir do iOS7, o método acima está obsoleto.
Use o próximo método em vez disso:

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

Acabei de descobrir que você precisa usar o presentViewController no iOS 5.

 [self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; 

A -> B -> C

Executar o código acima no modal C levará você de volta para A

Isso funcionou para mim, muito simples

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

Explicação:

Se você chamar dismiss em C, ele só poderá remover C. Se você chamar dismiss em B, ele fará a coisa certa: Remova o controlador de view modal mais alto. A primeira chamada, portanto, remove C (sem animação). A segunda chamada remove B.

A maneira mais fácil de acessar o controlador de visualização B de C é usar a variável presentingViewController.

Em B. Coloque:

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

Só execute uma animação.

Verifique isso para rápido:

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

Você só precisa de um comando de dispensa. Apenas descarte B, e então C irá embora.

Eu li todos os tópicos e não encontrei uma resposta adequada. Se você dispensar B, C desaparecerá imediatamente e criará um efeito estranho. A maneira correta é apresentar C como um controlador de visualização de criança com animação personalizada na parte inferior, 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) { }]; 

E então você simplesmente rejeita B e tudo parece muito melhor!

Isso funcionou para mim:

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

Em rápido 4

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

O controlador de navegação tem uma propriedade “viewControllers” que é uma matriz – você pode definir isso para uma nova matriz menos os dois controladores de exibição que você deseja remover.

Inspirado pela solução Albertos, criei um método delegado em B com um bloco para mostrar o resultado da exclusão de uma conta:

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

Eu enfrentei o mesmo problema, e uma solução melhor foi criar um “DismissViewProtocol” como segue:

Arquivo: DismissViewProtocol.h

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

Na minha visão B-modal, vamos responder para o método delegado:

no meu arquivo bh:

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

no meu arquivo bm:

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

No mesmo controlador B-view, quando eu chamo o Next, na minha view modal B, quando eu chamo a outra view modal C, supondo que para segue:

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

Finalmente, no meu arquivo ch, vamos nos preparar para o delegado:

 @property(nonatomic, weak) id  viewDelegate; 

E no meu arquivo cm, eu apenas digo ao meu viewDelegate para dispensar meu controlador de view modal e ele mesmo:

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

E é isso.

Espero que funcione para todos vocês.

Aqui está uma maneira de descartar mais de um controlador de exibição modal usando o ciclo de repetição:

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)