[Objective-C] デリゲート (Delegate)を理解する!
公開日:
:
最終更新日:2014/08/19
iPhone App 開発, Objective-C iPhone App, objective-c
Warning: Use of undefined constant user_level - assumed 'user_level' (this will throw an Error in a future version of PHP) in /home/users/1/juny/web/hidef/wp-content/plugins/ultimate-google-analytics/ultimate_ga.php on line 524
デリゲートとは?
デリゲートに関しての意味合いとして、”委譲”とか”代理”と説明されることが多いです。
簡単にいえば、”自分ができないことや、自分がやってほしいことを相手に頼む” ことです。
たとえば、2つの画面(ViewController)があるとします。
相手の画面から自分の画面が呼ばれました。
そしてアレコレ処理をして自分の画面が閉じられたときに、相手の画面にアラートを表示させるとか、自分の情報を保存してほしいときなどです。
自分の画面は閉じられてしまうので、自分では処理できない。それを他人にやってもらうわけです。
自分「もう眠いし寝ようかな。」
相手「いいよ。早く寝なよ。」
自分「自分はもうすぐ寝るけど寝たらやってほしいことあるんだけど...」
相手「なに?」
自分「紙にメモっといた。」←デリゲートの宣言
相手「わかったよ。あんたが寝たらやっておくよ。」
自分「頼んだ。」自分「zzz...」
相手「じゃあやるか。」←デリゲートの実行
ざっくりとストーリー仕立てにしてみました。(クオリティ低すぎる。。。)
では実装してみます!
わからない場合は、[Objective-C] UINavigationControllerのセグエを使って画面遷移をする を参考にしてください。
- 2つの画面(ViewController)を用意します。
- AiteViewController(相手の画面)
- JibunViewController(自分の画面)
- AiteViewControllerにNavigationControllerをEmbed inします。
- JibunViewControllerにNavigationControllerをEmbed inします。
- AiteViewControllerにButton(自分に遷移)を追加します。
- そのButtonからJibunViewController側のNavigationControllerにセグエを紐づけます。このときPushではなくModelにしてください。
- JibunViewControllerにButton(閉じる)を追加します。
- JibunViewControllerのButtonをヘッダーファイルに結びつけてボタンアクションを追加します。
Storyboardはこんな感じになりました。
処理の流れは...
- 相手の画面から自分の画面に遷移する
- 自分の画面が閉じられる(寝る)
- 相手の画面でログを出力する(メモをみて頼まれたことをやる)
デリゲート
ではこの場合、メモにあたるデリゲートを作成していきます。
メニューの「File > New > File…」からファイルを選択します。
テンプレートは「Objective-C protocol」を選択、ファイル名はMemoDelegateとします。
そして以下のように編集します。
#import <Foundation/Foundation.h> @protocol MemoDelegate <NSObject> - (void)buyTabako; - (void)washing; @end
メモに書いてあったのは「タバコを買いに行く」と「洗濯をする」です!
自分が寝たらこの2つを相手に実行させるのです!
頼む側:JibunViewController
ではJibunViewControllerの実装です。
JibunViewController.h(ヘッダーファイル)は以下の通りです。
#import <UIKit/UIKit.h> #import "MemoDelegate.h" @interface JibunViewController : UIViewController @property (weak, nonatomic) id <MemoDelegate> delegate; - (IBAction)buttonClosed:(id)sender; @end
自分がメモを作ったのですから、デリゲートをプロパティとして宣言します。
buttonClosedはボタンが押されたときのイベントになります。
次はJibunViewController.m(実装ファイル)のボタンイベントを以下の通りに編集します。
- (IBAction)buttonClosed:(id)sender { [self dismissViewControllerAnimated:TRUE completion:nil]; [self.delegate buyTabako]; [self.delegate washing]; }
ボタンを押されると自分は寝ます。
dismissViewControllerAnimatedで自分の画面が閉じられます。
そして相手にやってほしいことのメモ内容を書いときます。
頼まれる側:AiteViewController
次にAiteViewController.h(ヘッダーファイル)です。
#import <UIKit/UIKit.h> #import "MemoDelegate.h" @interface AiteViewController : UIViewController<MemoDelegate> @end
相手はこのメモを頼まれてるよーとカギかっこで宣言します。
そしてAiteViewController.m(実装ファイル)を編集します。
デリゲートを宣言した時点で、頼まれたことを書いてないよーと警告されているのがわかります。
なので頼まれごとを書いときます。以下のコード追加してください。
- (void)buyTabako { NSLog(@"%@", @"たばこ買いに行くよ!"); } - (void)washPants { NSLog(@"%@", @"洗濯するよ!"); }
NSLogでコンソールにメッセージを出力します。
そして、これが重要!
頼まれた人は頼んだ人のdelegateにself(頼まれた人自身)を設定してやります。以下のコードを追加してください。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showJibun"]) { UINavigationController *navigationController = segue.destinationViewController; JibunViewController *jibunViewController = [navigationController viewControllers][0]; jibunViewController.delegate = self; } }
prepareForSegueは画面遷移する前にする処理です。
segue.destinationViewControllerで遷移先の画面を取得します。
遷移先はNavigationControllerなので、その中に入っているJibunViewControllerを取得します。
[navigationController viewControllers]でナビゲーションで格納された画面(配列)が取得できます。その最初のViewControllerを配列の最初で指定して取得しています。
そしてself(自身)を設定します。
あとは、インポートするのを忘れずに。
#import "JibunViewController.h"
以上で、出来あがりです。さっそく実行してみましょう!
実行結果
まとめ
デリゲートは難しいですね。
今回の例に限らず、デリゲートというよりもイベントと解釈したほうがよいのかもしれません。「ボタンを押す→そのときに別のオブジェクトで特定の処理をする」みたいな感じですかね。
この記事を参考に、皆さんもぜひデリゲートを試してみてください!
ad
関連記事
-
-
NSDateを5分刻み・15分刻みで丸める
NsDateを初期値としてUIDatePicker等に設定する場合、日付の丸め処理が必要になるのでメ
-
-
小さなことからコツコツと
これまでHTMLとCSSだけで生きてきただけあって、プログラム言語がいまいちわからない。 Mo
-
-
OSSの使い方がわからない・・・。
チュートリアル系の、storyboradでview controllerを置いて画面遷移を設定してっ
-
-
[Objective-C] iPhoneアプリからのメーラー起動
今回はiPhoneアプリからメーラーを起動する処理を紹介します。 メーラー起動のコントローラー
-
-
[Swift] UITableViewのセルにアクションを設定する
セル選択→アクション UITableViewControllerを使用したテーブルビューの画面があ
-
-
[Swift] UINavigationControllerで戻るイベントを取得する
UINavigationController UINavigationControllerを使用し
-
-
[Swift] CoreDataで検索したデータを削除する
CoreDataの検索と削除 前の投稿 CoreDataを使ってみる をふまえて今度は検索&削除