Storyboard で UIViewController の dismiss を設定できるようにする
Storyboard で segue を設定して画面遷移を作っていく時、Modal 表示した ViewController にキャンセルボタンを設置する事がままある。
この時の ViewController への実装は
- (IBAction)cancel:(id)sender { [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; }
の様になる。
キャンセル操作の場合は完了(done)操作と違って ViewController を閉じる以外は何もしない上に、キャンセルボタンを実装する様々な ViewController の数だけこれと同じ実装を何度も行う事になる。
OS X の NSViewController
には
- (void)dismissViewController:(NSViewController *)viewController NS_AVAILABLE_MAC(10_10);
この dismiss メソッドの他にStoryboard上でアクションを接続できる
/* Dismisses the ViewController. If the presenter is a ViewController, it will be sent a -dismissViewController: message with this ViewController as the parameter. Does nothing if the receiver is not currently presented. */ - (IBAction)dismissController:(id)sender NS_AVAILABLE_MAC(10_10);
というメソッドが用意されている。
コメントによれば presenter が ViewController の場合 dismissViewController:
メソッドを自身を引数として呼ぶよう実装されているらしい。
実装の中身はこの様になっていると思われる。
- (IBAction)dismissController:(id)sender { [self.presentingViewController dismissViewController:self]; }
画面を閉じるだけの操作であればStoryboard上でこのアクションを接続するだけで良い。
これに習って iOS の方でもIBActionな dismiss メソッドを実装する。
UIViewController
のカテゴリ拡張として実装する事でどの ViewController でも使えるようになり、また IBAction として実装する事でStoryboard上でも利用できる。
かっちり実装するなら、カテゴリ名とメソッド名に prefix を付けてカテゴリ名は UIViewController+XXIBAction
メソッド名は - (IBAction)xx_dissmiss:(id)sender;
などにすると良い。
結果、以下の様にStoryboard上で dismiss のアクションを設定できるようになる。
図では画面左下の ViewController から Modal で NavigationController を表示し、NavigationController の rootViewController が画面右上の ViewController になっている。
キャンセルボタンに dismiss: を設定し実行すると画面左下の ViewController に戻る。
一つこのカテゴリを実装しておくとStoryboard上で完結できる事が増えて楽になる。