Cocoaの[UIControl addTarget:action:forControlEvents:]
ではaction
に設定するセレクタに引数を渡すことができないので、
category
とblocks
を利用して、自由に定義したコールバックを渡せるようにする。
ファイル名はUIControl+Blocks
とする。まずはヘッダファイルを定義。
1
2
3
4
| #import <UIKit/UIKit.h>
@interface UIControl(Blocks)
- (void)addTargetWithBlocks:(void (^)())blocks forControlEvents:(UIControlEvents)forControlEvents;
@end
|
次に実装ファイルを定義。category
内ではインスタンス変数を保持できないので、関連参照を用いてblocks
をストアする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #import "UIControl+Blocks.h"
#import <objc/runtime.h>
@implementation UIControl(Blocks)
- (void)addTargetWithBlocks:(void (^)())blocks forControlEvents:(UIControlEvents)forControlEvents {
objc_setAssociatedObject(self, @"key", blocks, OBJC_ASSOCIATION_COPY);
[self addTarget:self action:@selector(callback:) forControlEvents:forControlEvents];
}
- (void)callback:(id)sender {
void (^blocks)() = objc_getAssociatedObject(self, @"key");
if (blocks) {
blocks();
}
}
@end
|
後は、任意のクラスでヘッダファイルをインポートすれば、[UIControl addTargetWithBlocks:forControlEvents:]
が利用できる。
1
2
3
| [btn addTargetWithBlocks:^{
NSLog(@"%@", @"hoge");
} forControlEvents:UIControlEventTouchUpInside];
|