EDIT: The "correct" mechanism to do this in iOS5+ would be to use the – dismissViewControllerAnimated:completion:
method, and present the sequential view controller from the completion block.
The viewcontroller that is being shown modally will have its viewDidDisappear:animated: method called once the modal-dismissal-animation is complete. AFIK this is the only place you can hook to initiate a subsequent presentModalViewController:animated: call.
I have a class that I use for presenting modal view controllers and it implements the logic you re looking for via a callback to the presenting view controller once the dismissal is complete. To use this class, simply alloc/init an instance and present using the normal presentViewController:animated: call. Implement the following method on the presenting view controller:
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
This will be called at once the modal view controller is gone, and you can present a new modal view controller at this time.
One nice thing too - since this class is a specialization of UINavigationController, you can configure the navigationBar on/off as you like. The class also has built-in logic to show a dismiss button, as you like.
Here s the class definition:
@protocol TSModalViewControllerDelegate
- (void) modalViewControllerDidDismiss: (UIViewController*) modalViewController;
@end
@interface TSModalViewController : UINavigationController
{
UIViewController* _originalParentViewController;
}
@property BOOL dismissButtonHidden;
- (id) initWithViewController: (UIViewController*) vc;
- (id) initWithClass: (Class) c;
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
@end
And the class implementation:
@implementation TSModalViewController
@synthesize dismissButtonHidden;
- (id) initWithViewController: (UIViewController *)vc
{
return [super initWithRootViewController: vc];
}
- (id) initWithClass:(Class)c
{
UIViewController* vc = [[[c alloc] init] autorelease];
return [self initWithViewController: vc];
}
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
UIViewController* vc = [[[c alloc] initWithNibName:nibNameOrNil bundle:nibBundleOrNil] autorelease];
return [self initWithViewController: vc];
}
- (void) viewDidAppear: (BOOL) animated
{
[super viewDidAppear: animated];
[_originalParentViewController release];
_originalParentViewController = [self.parentViewController retain];
if (!self.dismissButtonHidden)
{
UIBarButtonItem* dismissButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemStop
target: self
action: @selector(onDismiss:)] autorelease];
UIViewController* rootViewController = [self.viewControllers objectAtIndex:0];
rootViewController.navigationItem.leftBarButtonItem = dismissButton;
self.navigationBarHidden = NO;
}
}
- (void) viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear: animated];
if ( [_originalParentViewController respondsToSelector: @selector(modalViewControllerDidDismiss:)] )
{
[_originalParentViewController performSelector: @selector(modalViewControllerDidDismiss:) withObject: self];
}
}
- (void) dismissModalViewControllerAnimated:(BOOL)animated
{
return [self.parentViewController dismissModalViewControllerAnimated: animated];
}
- (void) onDismiss: (id) sender
{
[self.parentViewController dismissModalViewControllerAnimated: YES];
}
- (void) didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void) viewDidUnload
{
[super viewDidUnload];
}
- (void)dealloc
{
[_originalParentViewController release];
[super dealloc];
}
@end
and, here s how you can use it (in the context of some normal view controller):
- (void) onShowIt:(id)sender
{
TSModalViewController* mvc = [[[TSModalViewController alloc] initWithClass: [MyModalViewController class] nibName: @"MyModalViewController" bundle:nil] autorelease];
mvc.dismissButtonHidden = YES; // set to no if you don t want an "automatic" close button
[self presentModalViewController: mvc animated: YES];
}
and, here is the dismissal callback method, which presents a new modal view controller:
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
{
MyModalViewController* vc = [[[MyModalViewController alloc] initWithNibName: @"MyModalViewController" bundle:nil] autorelease];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
TSModalViewController* mvc = [[[TSModalViewController alloc] initWithViewController: vc] autorelease];
[self presentModalViewController: mvc animated: YES];
}