モーダルビュー(modalView)とデリゲート(delegate) | cowのブログ

モーダルビュー(modalView)とデリゲート(delegate)

デリゲート( delegate ) で悪戦苦闘~叫び
設定画面で入力された値をメインに反影させるだけでめちゃくちゃ悩んでしまった。
今回参考にさせていただいたblog

▶テン*シー*シー[【iPhoneアプリ開発ドリル】モーダルビューを表示する(2)]
右矢印残念ながら理解できなかったf^^;
▶Sun Limited Mt.[[iPhone] モーダルビューの非表示、値の受け渡しはデリゲートで行う]
右矢印なんとなくわかった気になったけど、最初は動かなかったf^^;
      動いた後、再度プログラムを見ると何故動かなかったのかがわかった。
▶Everything was born from Love[Study CoreData 7 ~親子三代奮闘記~]
  右矢印理屈がわかった。なんとなくわかった・・・
      考え方はとても参考になった。
▶timneill your second opinion[Modal View Controller Example – Part 2]
  右矢印国内でサンプルが見つけられなかったので [modalview delegate ]でぐぐった。
      サンプルがあったので参考にしながら作ったら動いた。にひひ

■テスト用に作ったサンプル
モーダルビュー(子画面)で色を設定し、メインビュー(親画面)に反影させる。
cowのブログcowのブログモーダルビュー(子画面)で表示された画面の色ボタンをタップするとメイン画面(親画面)の色が変わる。
▶Everything was born from Love[Study CoreData 7 ~親子三代奮闘記~]
↑ここのたとえ拡張させて・・・
子供が親に直接言えないから伝書鳩を使って伝える・・・みたいな・・・・

デリゲート( delegate )が伝書鳩で・・・
まず、子供は伝書鳩を使うよ~って宣言する!(@protocol ColorSelectDelegate;)
子供は伝書鳩をまず準備する!(id<ColorSelectDelegate> colorSelectdelegate_;)
伝書鳩に手紙を持たせる!([colorSelectdelegate_ selectColor:requestColor];)

親は、伝書鳩で来るんだなと待ち構える(@interface ModalViewController : UIViewController <ColorSelectDelegate>)
いつ来てもいいように伝書鳩のおうちを準備しとく!(@protocol ColorSelectDelegate
-(void)selectColor:(UIColor*)inColor; // デリゲートメソッド
@end)
伝書鳩が持って来た手紙を開封する(-(void)selectColor:(UIColor*)inColor; // デリゲートメソッド)

ん~わかりづらいたとえか・・・・叫び
じゃぁパス!

モーダルビュー(子画面)側の設定:
モーダルビュー(子画面)で設定(入力)された値を親画面にデータを反影(メッセージを送信、データを受け渡す)させるためにデリゲート( delegate )の機能を持たせる。
今回は色のデータを受け渡したいので、 ColorSelectDelegate としました。
ColorSelectDelegate を使いますよ~って宣言をします。
デリゲート用のインスタンス変数とプロパティ(assign属性)を追加。

親画面の設定:
モーダルビュー(子画面)からの デリゲート( delegate )に対応させるためにプロトコルを宣言する。
デリゲート( delegate ) を読み込ませるために ColorSetViewController.h を読み込ませる。
デリゲート( delegate ) を追加する。
デリゲート( delegate ) のメソッド( -(void)selectColor:(UIColor*)inColor; )を使うよ~って宣言する。
デリゲート用メソッドを追加。

プロジェクト名:Modal
ModalViewController.h(親画面側)
#import <UIKit/UIKit.h>
// 色データを送るためのプロトコルを作る
@protocol ColorSelectDelegate
-(void)selectColor:(UIColor*)inColor; // デリゲートメソッド
@end
@interface ModalViewController : UIViewController <ColorSelectDelegate>{ // 使用するデリゲートを宣言する
IBOutlet UIBarButtonItem *colorButton;
}
@property (nonatomic, retain) IBOutlet UIBarButtonItem *colorButton;
//*********************************************************
// [COLOR] ボタンが押された時の処理
- (IBAction)ButtonAction:(UIBarButtonItem *)sender;
@end
ModalViewController.m
#import "ModalViewController.h"
#import "ColorSetViewController.h"
@implementation ModalViewController
@synthesize colorButton;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.colorButton = nil;
}
- (void)dealloc {
[colorButton release];
[super dealloc];
}
//*********************************************************
// COLOR BUTTON
- (IBAction)ButtonAction:(UIBarButtonItem *)sender {
ColorSetViewController *colorSetView = [[ColorSetViewController alloc]
initWithNibName:@"ColorSetViewController" bundle:nil];
colorSetView.colorSelectdelegate_ = self;
// モーダルビューを開く
[self presentModalViewController:colorSetView animated:YES];
}
// デリゲートメソッドの処理
-(void)selectColor:(UIColor*)inColor {
// nil はキャンセルとする。
if (inColor != nil)
self.view.backgroundColor = inColor; // 色を変える
// モーダルビューを閉じる
[self dismissModalViewControllerAnimated:YES];
}
@end
ColorSetViewController.h
// tag No. を設定

// IB で tag No. を対応する数値を入れること!

#define kRED 0
#define kGREEN 1
#define kWHITE 2
#define kCANCEL 99
#import <UIKit/UIKit.h>
// デリゲート プロトコルを宣言する
@protocol ColorSelectDelegate;
@interface ColorSetViewController : UIViewController {

// デリゲート用インスタンス
id<ColorSelectDelegate> colorSelectdelegate_;
IBOutlet UIButton *redButton;
IBOutlet UIButton *greenButton;
IBOutlet UIButton *whiteButton;
IBOutlet UIButton *cancelButton;
}
@property (nonatomic, assign) id<ColorSelectDelegate> colorSelectdelegate_;
@property (nonatomic, retain) IBOutlet UIButton *redButton;
@property (nonatomic, retain) IBOutlet UIButton *greenButton;
@property (nonatomic, retain) IBOutlet UIButton *whiteButton;
@property (nonatomic, retain) IBOutlet UIButton *cancelButton;
//*********************************************************
// COLOR BUTTON
- (IBAction)colorSelectButtonAction:(UIButton *)sender;
@end
ColorSetViewController.m(子画面側)
#import "ColorSetViewController.h"
#import "ModalViewController.h"
@implementation ColorSetViewController
@synthesize colorSelectdelegate_;
@synthesize redButton;
@synthesize greenButton;
@synthesize whiteButton;
@synthesize cancelButton;
- (void)viewDidUnload {
[super viewDidUnload];
self.redButton = nil;
self.greenButton = nil;
self.whiteButton = nil;
self.cancelButton = nil;
self.colorSelectdelegate_ = nil;
}
- (void)dealloc {
[ redButton
release];
[ greenButton
release];
[ whiteButton
release];
[ cancelButton
release];
[super dealloc];
}
//*********************************************************
// COLOR BUTTON
- (IBAction)colorSelectButtonAction:(UIButton *)sender {
UIColor* requestColor = nil;
// 押されたボタンに合わせて色を設定する
switch (sender.tag) {
case kRED:
requestColor = [UIColor redColor];
break;
case kGREEN:
requestColor = [UIColor greenColor];
break;
case kWHITE:
requestColor = [UIColor whiteColor];
break;
case kCANCEL:
requestColor = nil;
break;
default:
break;
}
// デリゲートで色データを渡す
[colorSelectdelegate_ selectColor:requestColor];
}
@end
ModalViewController.xib
cowのブログ
ColorSetViewController.xib
cowのブログ

*モーダルビュー( modalView ) は親画面で閉じた方がいいらしい。
でも、ぐぐって見つかるサンプル、出版物のサンプルもほとんどが子画面で閉じてる気がする。
▶iOS View Controller プログラミングガイド (116p)
モーダルView Controllerを閉じる
モーダルView Controllerを閉じるときによく使われるアプローチは、親のView Controllerに閉じさせ る方法です。つまり、できる限り、そのモーダルView Controllerを表示したのと同じView Controller が閉じるべきなのです。


クリップModal.zip