4

In iOS 4, if you want to dismiss two nested modal view controllers, the following code works:

[[[[self parentViewController] parentViewController] parentViewController] dismissModalViewControllerAnimated:YES];

However in iOS 5 this method no longer works. Does anybody know how to achieve this result in iOS 5?

Andrew Lauer Barinov
  • 5,694
  • 10
  • 59
  • 83

3 Answers3

11

If you call dismissViewControllerAnimated: on the view controller that presented the first modal, you'll dismiss of both modals at once. So in your 2nd modal you would do the following:

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
Karl Monaghan
  • 880
  • 9
  • 14
8

I have an app that closes nested modal view controllers through NSNotificationCenter. The notification is received by the VC that I want to navigate back to and all the VC's in between are gone.

In the deeper VC...

NSNotification * notification = [NSNotification notificationWithName:@"BACKTOINDEXNOTE" object:nil];
[[NSNotificationCenter defaultCenter] postNotification:notification];

In the VC I would like to go back to

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
   self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
   if (self) {
       [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismiss) name:@"BACKTOINDEXNOTE" object:nil];

       // more init code
   }
   return self;
}

-(void)dismiss
{
  [self dismissModalViewControllerAnimated:YES];
}

This works on iOS 5 device with a project deployed for 4.0+ I hope it helps. If you use this, it will scale to support more VC's in between your current VC and the one you want to dismiss to, without changing this code

Jesse Black
  • 7,966
  • 3
  • 34
  • 45
  • Dismissing a modal view controller automatically dismisses all the modal view controllers that were children of the one you dismissed. So it's scalable anyway. I mean if mvc1 presents mvc2 and mvc2 presents mvc3 and you dismiss mvc1 , both mvc2 and 3 will be dismised. – George Apr 12 '12 at 10:21
  • @user624091 The OP's code wouldn't scale properly if there was another viewcontroller thrown in the chain between self and the "great-grand" parent. Both my code and OP's code take advantage of the fact that dismissing a view controller can dismiss more than one controller. From my experiences when requesting a view controller to dismiss it will 1) Dismiss itself if it has no children, 2) Dismiss all of its children if they were presented modally – Jesse Black Apr 12 '12 at 13:21
  • Very interesting solution. Don't forget that viewcontrollers on iOS 5 have `presentedViewController` and `presentingViewController` properties too. There is also a `dismissViewControllerAnimated:completion:` where the completion parameter can take a ^block. – Rog Apr 29 '12 at 03:37
0

For a stack of two modals call this baby from your delegate method on the initial presenter to jump back down the stack and nuke the presented VCs.

[self.presentedViewController.presentedViewController dismissViewControllerAnimated:NO completion:nil];
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];

Obviously it's a bit brittle because if you start adding more modals then things will break. Generally if you're doing a stack of controllers you would use UINavigationController, but for a couple of modals this does the trick and is a lot less complex than setting up notifications or even more delegates!

SmileBot
  • 19,393
  • 7
  • 65
  • 62