views:

342

answers:

1

Scenario:
1. Show navigation controller based view
2. User select option
3.   Show modal view A
4. User select another option in modal view A
5.   Hide modal view A
6.   Show modal view B

// This function must show modal view A
This scenario implemented like this:
- (IBAction)showModalViewA:(id)sender {
    ModalViewA *viewA = [[ModalViewA alloc] forParent:self];
    [self presentModalViewController:viewA animated:YES];
    [viewA release];
}

// This function must hide modal view A and show modal view B
- (void)didSelectOptionInViewA {
    ModalViewB *viewB = [[ModalViewB alloc] init];
    viewB.peoplePickerDelegate = self;

    [self dismissModalViewControllerAnimated:NO];            // Problem Is Here
    [self presentModalViewController:viewB animated:YES];
    [viewB release];
}

Please look at line marked as // Problem Is Here
When I set the dismissModalViewControllerAnimated:NO it works fine. If this parameter is YES then viewB did not appear on the screen.

How to make it works with animation?

A: 

The animation will take some time, something like 0.3 seconds. You cannot see when the animation has finished (no delegate methods are being sent) so you can do 2 things:

  1. Present the new modal view controller in a new method and call that method with a delay of 0.3 seconds. This is not an ideal solution because animation times may vary and you can never be sure that the animation has really finished.
  2. Add some kind of a flag instance variable to your main view controller (the one which presents the modal view controller) and set that flag to YES (or do it using bits, then one flag can contain multiple options). Then check in -[UIViewController viewDidAppear:] whether that flag is set and when it is, present the modal view controller.
    1. You can be sure the animation has finished.
    2. Presenting a modal view controller should be done within it's main view controller

I really wonder why you would want to do such a thing, because this is really not very Apple-ish. You'd better present the new modal view over the old modal view or you try to find another design pattern which solves the problem properly, which would be even better.

JoostK
I'm doing this when an image picker returns and I need to take some action on the given image. I don't want to start the action until the picker has fully dismissed, so I set a flag earlier and check for it in `-viewDidAppear:`.
Michael Grinich