Question

I have a modal view that is presented via UIModalTransitionStylePartialCurl transition. In that modal view there is a button, which I would like to:

  1. dismiss the current modal view (curl down), then
  2. present a new modal view (cover vertical).

However, when I try the following, it simply dismisses the curl modal view but doesn't present the new one:

[self dismissModalViewControllerAnimated:YES];
NewView *vc = [[NewView alloc] init];
[self.parentViewController presentModalViewController:vc animated:YES];

I have a feeling it has to do with that last line. Presenting NewView on self doesn't work either. How can I accomplish this?

Was it helpful?

Solution

Are you using iOS 5?

If so the problem you are seeing is due to a change documented here: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/parentViewController

The important bit at that link is this:

Prior to iOS 5.0, if a view did not have a parent view controller and was being presented modally, the view controller that was presenting it would be returned. This is no longer the case. You can get the presenting view controller using the presentingViewController property.

So changing to self.presentingViewController may fix your issue, but probably will not.

Using this code from your first modal:

[self dismissModalViewControllerAnimated:YES];
SecondViewController *sec = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
sec.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.presentingViewController presentModalViewController:sec animated:YES];

You don't see the new view controller presented.

To get what you are after you want to use a new (as of iOS5) method:

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion

This method is the recommended replacement for presentModalViewController.

And a custom method on your first view controller, something like:

- (void)cycleModalViewControllersWithController:(UIViewController *)newViewController

That method can both dismiss your current modal and present the new one, something like this:

- (void)cycleModalViewControllersWithController:(UIViewController *)newViewController {
    [self dismissViewControllerAnimated:YES completion:^{
        [self presentViewController:newViewController animated:YES completion:NULL]; 
    }];
}

Using the completion block to launch the new modal let's you wait until the old modal has animated out. So in your second modal view controller you would call your custom method on your first modal view controller and let it manage dismissing/presenting the new one.

OTHER TIPS

The first thing to verify would be if self.parentViewController is nil or not.

NSLog(@"parent == %@", self.parentViewController);

if it's nil (in my test it was nil) you will need to pass a pointer to your parent in that modal view. And after that you could do something like this

[self.caller performSelector:@selector(launchNewView:) 
                  withObject:nil 
                  afterDelay:1.0];
[self.caller dismissModalViewControllerAnimated:YES];

here self.caller is the "parent" that was set on the UIViewController just before it was presented modally.
I don't find this to be a perfect solution, but it's working in my test.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top