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を閉じる)に記載してあります。

まだブロック構文でコールバックを記述する方法がよく分かっていない、、