J'ai 2 contrôleurs de vue présentés modalement.
A presents B which presents C.
Lorsque je rejette C, je voudrais également rejeter B. Mais je ne sais pas comment faire cela:
Rejeter C:
[self dismissModalViewControllerAnimated:YES]
//[delegate dismissB] //this doesn't work either when i create a delegate pattern
Maintenant, je reste avec B. Comment puis-je écarter B de C?
Essayez d’utiliser le code suivant dans B (juste après avoir supprimé C, comme vous le faites déjà):
[self.parentViewController dismissModalViewControllerAnimated:YES];
IMPORTANT:
Ne faites rien dans la méthode après cette ligne.
Ce contrôleur de vue (B) sera probablement publié et désalloué ...
METTRE À JOUR:
À partir de iOS7, la méthode ci-dessus est obsolète.
Utilisez la méthode suivante à la place:
[self.parentViewController dismissViewControllerAnimated:YES completion:^{ /* do something when the animation is completed */ }];
Je viens de découvrir que vous devez utiliser présenterViewController dans iOS 5.
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];
A -> B -> C
Exécuter le code ci-dessus en modal C vous ramènera à A
Cela a fonctionné pour moi, très simple
// Call inside View controller C
self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Explication:
Si vous appelez licenciement sur C, il ne peut supprimer que C. Si vous appelez licencié sur B, vous ferez bien: Supprimez le plus haut contrôleur de vue modale. Le premier appel supprime donc C (sans animation). Le deuxième appel supprime B.
Le moyen le plus simple d'accéder au contrôleur de vue B à partir de C consiste à utiliser la variable présentantViewViewController.
En B. Mettez:
[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];
Exécuter une seule animation.
Vérifiez ceci pour Swift:
self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil);
Dans Swift 4
self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil);
J'ai lu tous les sujets et je n'ai pas trouvé de réponse appropriée. Si vous rejetez B, C disparaît immédiatement et crée un effet étrange. La manière appropriée est de présenter C en tant que contrôleur de vue enfant avec une animation personnalisée partant du bas, comme suit:
[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) {
}];
Et puis vous rejetez simplement B et tout semble beaucoup plus joli!
Vous n'avez besoin que d'une commande de renvoi. Il suffit de rejeter B, puis C partira avec.
Cela a fonctionné pour moi:
// Swift
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
// Objective-C
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
Inspiré par la solution Albertos, j'ai créé une méthode de délégation en B avec un bloc pour afficher le résultat de la suppression d'un compte:
#pragma - mark - AddAccountViewControllerDelegate Methods
- (void) dismissToSettings {
[self dismissModalViewControllerAnimated:NO];
[self dismissViewControllerAnimated:YES completion:^(void){[DKMessage showMessage:LS(@"Account was successfully created")];}];
}
Voici un moyen de rejeter plusieurs contrôleurs de vue modaux à l'aide d'un cycle de répétition:
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)
J'ai rencontré le même problème, et une meilleure solution créait un "DismissViewProtocol" comme suit:
Fichier: DismissViewProtocol.h
@protocol DismissViewProtocol <NSObject>
-(void)dismissView:(id)sender;
@end
Dans ma vue B-modal, répondons pour la méthode delegate:
dans mon fichier b.h:
#import "DismissViewProtocol.h"
@interface B-Modal : UIViewController <DismissViewProtocol>
...
@end
dans mon fichier b.m:
-(void) dismissView:(id)sender
{
[((UIViewController *) sender) dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];
}
Dans le même contrôleur de vue B, lorsque j'appelle le , Ensuite, dans ma vue modale B, lorsque j'appelle l'autre vue modale C, en supposant que pour segue:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
((C-ViewController *)segue.destinationViewController).viewDelegate=self;
}
Enfin, dans mon fichier c.h, préparons le délégué:
@property(nonatomic, weak) id <DismissViewProtocol> viewDelegate;
Et dans mon fichier c.m, je viens de dire à mon viewDelegate de rejeter mon contrôleur de vue modal et lui-même:
-(void)closeBothViewControls
{
[self.viewDelegate dismissView:self];
}
Et c'est tout.
J'espère que cela fonctionne pour vous tous.
Le contrôleur de navigation a une propriété "viewControllers" qui est un tableau - vous pouvez le définir sur un nouveau tableau moins les deux contrôleurs de vue que vous souhaitez supprimer.