UIStoryboardのmodalを閉じた時に元の画面に異なる処理をする
前回はモーダルビューを表示して、もとのビューに戻るまで試しました。
今回は戻った時に選択されたボタンに応じて、もとのビューに異なった処理してみます。
Redが押されたらStory1を赤に、Blueが押されたら青にします。
なんか図はごちゃごちゃして見にくくなってしまいました。
進めてみればなんとなく分かると思います。
前回の続きから進めていきます、
まずMainStoryboard.storyboardにボタンを2つ追加して、
ボタン番号を識別するためのタグをセットします。
「Red」は1で「Blue」は2です。
次にViewControllerを右クリックして作成済みのActionを見つけ、
controlを押しながらコネクタを「red」ボタンに繋げます。
イベントは「touch up inside」を選択します。
同様に「blue」ボタンにも繋げます。
これで1つのActionに複数のボタンが紐付けられました。
次にMyModalView.hファイルとmファイルを以下の様に変更します。
まずMyModalViewにプロトコルを定義し、
MyModalViewになにかがおこった時に処理を通知するようにしたいので、
何かあった際の連絡先オブジェクトとして、delegateを作成します。
MyModalView.hファイル
#import <UIKit/UIKit.h> //デリゲート用のプロトコルの作成 @protocol MyModalDelegate <NSObject> - (void)modalViewDidDissmissed:(NSInteger)tag; @end @interface MyModalView : UIViewController { id<MyModalDelegate> delegate; } @property(nonatomic,assign)id<MyModalDelegate> delegate; - (IBAction)dissmissModal:(id)sender; @end
MyModalView.mファイル
//delegateの@synthesizeを追加 @implementation MyModalView @synthesize delegate;
MyModalView.mファイルdissmissModalメソッド
- (IBAction)dissmissModal:(id)sender { //これは使わないので削除かコメント //[self dismissModalViewControllerAnimated:YES]; UIButton *btn = nil; if ([sender isKindOfClass:[UIButton class]]) { btn = (UIButton*)sender; } //デリゲートがメソッドに応答できるかチェックしてから呼び出す if ([delegate respondsToSelector:@selector(modalViewDidDissmissed:)]) { [delegate modalViewDidDissmissed:btn.tag]; } else { NSLog(@"can not call modalViewDidDissmissed"); } }
プロトコルはインターフェイスとして使えるメソッド定義の集まりで、
定義と採用に分かれています、以下のようにStory1ViewController.hを変更すると、
プロトコルMyModalDelegateを採用するという意味になり、
定義元で準備してあるメソッドを実装し使うことができます。
Story1ViewController.hファイル
#import <UIKit/UIKit.h> #import "MyModalView.h" @interface Story1ViewController : UIViewController<MyModalDelegate> @end
今回の内容はプロトコルの説明用ではないので、
詳しい説明は以下サイトさん等も参考にしてみて下さい。
でらうま倶楽部:Objective-C プロトコルを最短で理解するプログラム例
最後にStory1ViewController.mファイルに、
セグエが実行される度に呼ばれるprepareForSequeメソッドを実装し、
その中で次の画面のdelegate通知先として自分(Story1ViewController)を登録します。
その後、採用したプロトコルのモーダルビューが片付けられる時に呼ばれるメソッドを実装します。
Story1ViewController.mファイル
//デフォルトコードは省略 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } //追加 セグエが実行される前に毎回呼び出されるメソッド - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { //通知先として自分を登録 MyModalView *modalView = (MyModalView *)segue.destinationViewController; modalView.delegate = self; } //追加 MyModalViewDelegateのメソッド - (void)modalViewDidDissmissed:(NSInteger)tag { //デリゲートメソッド内でtagによって分岐処理をする [self dismissModalViewControllerAnimated:YES]; NSLog(@"%ld",(long)tag); if (tag == 1) { [self.view setBackgroundColor:[UIColor redColor]]; } else if(tag == 2){ [self.view setBackgroundColor:[UIColor blueColor]]; } } @end
これで「red」ボタンを押した時に赤色に、
「blue」ボタンを押した時に青色にViewの背景色が変わるはずです。
このモーダルビューの片付け方は、
iOS View Controllerプログラミングガイド(モーダルViewControllerを閉じる)に記載してあります。
まだブロック構文でコールバックを記述する方法がよく分かっていない、、