最近つかっている NSNotificationCenter がかなり便利だったのでまとめてみた。
delegate を使わずにメソッド実行を委任できるものである。
前回の内容は開発者なら誰でも使うやり方だと思うが、
今回のは知らない人も多いだろう。
初めて見たときに、ええ!こんなふうにできるの!めっちゃ便利!!
と私は思ったし、おすすめ。
今回使うメソッドは以下の3つ
NSNotificationCenter
[[NSNotificationCenter defaultCenter] addObserver: selector: name:object:]
[[NSNotificationCenter defaultCenter] removeObserver: name: object:]
[[NSNotificationCenter defaultCenter] postNotificationName:object:userInfo:]
delegateを使わずに、クラス間でメソッドを実行できる。
特に画面遷移やオブジェクト渡しが簡単にできる。
実装は以下のとおり。
ViewController.h
#import "TouchImageView.h"
@interface ViewController : UIViewController
@property (strong, nonatomic) TouchImageView *imageView;
@end
ViewController.m
static NSString * const kDetail = @"detail";
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//タッチできる画像を配置する
imageView = [[TouchImageView alloc] initWithImage:[UIImage imageNamed:@"sasamisan"]];
imageView.userInteractionEnabled = YES;
imageView.frame = CGRectMake(100, 100, 200, 300);
[self.view addSubview:imageView];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// @"detail" という文字列で通知を受け取れるようにする
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showDetailViewController) name:kDetail object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
//通知を終了
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//ほかのViewControllerに遷移する
-(void)showDetailViewController:(NSNotification *)notification{
//渡されたオブジェクトから取り出す
UIImageView *iv = (UIImageView *)[notification object];
NSDictionary *userInfo = [notification userInfo];
//詳細画面に遷移する
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.image = iv.image
dvc.userName = userInfo[@"name"];
dvc.sex = userInfo[@"sex"];
[self.navigationController:dvc animated:YES];
}
@end
TouchImageView.h
@interface TouchImageView : UIImageView
@end
TouchImageView.m
static NSString * const kDetail = @"detail";
@implementation TouchImageView
//タッチされたら、その画像の詳細に遷移する
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//メソッドに渡す値を設定する
NSDictionary *dic = @{@"name": @"sasami", @"sex":@"female"};
//kDetailという文字列を通知する。一緒にオブジェクトをいろいろ渡す
[[NSNotificationCenter defaultCenter] postNotificationName:kDetail object:self userInfo:dic];
}
@end
DetailViewController は割愛。
postNotificationName:kDetail object:self userInfo:dic
の部分でobject:
とuserInfo:
に指定された変数は、NSNotification
というクラスでまとめられて、通知先のメソッドの第一引数となる。渡すオブジェクトがないならnil
を入れておこう。