編集: iOS5 +でこれを行うための「正しい」メカニズムは、– dismissViewControllerAnimated:completion:
メソッドを使用し、完了ブロックからシーケンシャルビューコントローラーを提示することです。
モーダルで表示されているビューコントローラのviewDidDisappear:animated:メソッドは、modal-dismissal-animationが完了すると呼び出されます。AFIKこれは、後続のpresentModalViewController:animated:呼び出しを開始するためにフックできる唯一の場所です。
モーダルビューコントローラーを提示するために使用するクラスがあり、却下が完了すると、提示するビューコントローラーへのコールバックを介して探しているロジックを実装します。このクラスを使用するには、インスタンスを割り当て/初期化し、通常のpresentViewController:animated:呼び出しを使用して提示します。表示しているViewControllerに次のメソッドを実装します。
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
これは、モーダルビューコントローラーがなくなるとすぐに呼び出され、この時点で新しいモーダルビューコントローラーを提示できます。
また、このクラスはUINavigationControllerの特殊化であるため、navigationBarのオン/オフを自由に構成できます。このクラスには、必要に応じて、却下ボタンを表示するロジックも組み込まれています。
クラスの定義は次のとおりです。
@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
そしてクラスの実装:
@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
そして、これがあなたがそれを使うことができる方法です(いくつかの通常のViewControllerのコンテキストで):
- (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];
}
そして、これが却下コールバックメソッドです。これは新しいモーダルビューコントローラーを提供します。
- (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];
}