4

I got dismissModalViewControllerAnimated to work properly on the following setup but am confused as to why it works on self (the modalViewController) rather than the parentViewController.

Here's the setup:

  1. I have a UITableViewController with a nav button that calls up a modal view:


    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.title = @"Root";

        _data = [NSArray arrayWithObjects:@"One", @"Two", nil];
        _detailController = [[DetailViewController alloc] init];

        // Uncomment the following line to preserve selection between presentations.
        // self.clearsSelectionOnViewWillAppear = NO;

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem;

        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showAbout)];
    }

    - (void)showAbout
    {
        AboutViewController *abv = [[AboutViewController alloc] init];
        abv.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
        [self presentModalViewController:abv animated:YES];
    }

Here's the modal view controller AboutViewController with a toolbar button that triggers a dismiss action to close the modal:



    - (IBAction)dismissAction:(id)sender {
        [self dismissModalViewControllerAnimated:YES];
    }

My question is why does [self dismissModalViewControllerAnimated] work rather than [self.parentViewController dismissModalViewControllerAnimated] ?? Is this new in iOS 5? I thought only the parentViewController is capable of dismissing a child modal view?

Thanks!

LeoAlmighty
  • 91
  • 2
  • 5

2 Answers2

10

[self dismissModalViewControllerAnimated:YES]; Has worked for quite some time. One of the best kept secrets in iOS development if you ask me.

However self.parentViewController not working is in fact new to iOS 5. It has been 'replaced' with self.presentingViewController.

This causes an interesting problem for code trying to be pre-iOS 5 compatible. Since as you have found self.parentViewController returns nil on iOS 5. And UIViewControllers do not respond to presentingViewController pre-iOS 5.

It leaves us doing something like this:

if ([self respondsToSelector:@selector(presentingViewController)]){
    [self.presentingViewController dismissModalViewControllerAnimated:YES];
}
else {
    [self.parentViewController dismissModalViewControllerAnimated:YES];
}
NJones
  • 27,139
  • 8
  • 70
  • 88
  • `[self.presentingViewController dismissModalViewControllerAnimated:YES]` is dismissing the current view for me. I have 3 levels of modal and want to get rid of 2 of them but this is taking me back to the second level. Any idea? – Andre Cytryn Sep 05 '12 at 20:27
  • @AndréCytryn Yes I have some ideas on that. And I wrote them in an [answer to your question here.](http://stackoverflow.com/a/12293642/927947) – NJones Sep 06 '12 at 05:44
8

Instead of using what NJones has said, I would suggest sticking to

[self dismissModalViewControllerAnimated:YES]

The reason this will work for all the OSes is stated in the documentation itself:

"The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, however, it automatically forwards the message to the presenting view controller."

NOTE: A note about this method in iOS5.0 though. dismissModalViewControllerAnimated: method has been deprecated. dismissViewControllerAnimated:completion: should be used over here instead.

Kevin Bedell
  • 13,254
  • 10
  • 78
  • 114
Jas
  • 77
  • 1
  • 2