IOS UIControl使用block作为事件捕获回调

对于继承自UIControl的target-action模式,需要使用如下方式进行事件捕获

- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

其中的参数action是一个SEL(@selector),需要重新定义一个新的类成员函数,事件较多时往往需要添加更多的函数,较为麻烦。如果能使用代码块block来支持事件响应,则会方便很多。

后来在Github上看到zwaldowski/BlocksKit,该库对Objective-C提供了更多block语法支持的,其中就包括了UIControll的事件支持。

在文件UIControl+BlocksKit.m中实现了UIControl的分类,增加了add,remove,has三种事件管理,在bk_addEventHandler中,将block作为参数传入,然后对block和响应的forControlEvents通过addTarget映射到一个新的自定义的BKControlWrapper类中,即是每添加一个事件,将事件作为block作为传入创建一个新的接受事件的类实例,用该对象作为事件的接受者,实现实在是精妙!

BKControlWrapper的部分核心代码如下

@interface BKControlWrapper : NSObject <NSCopying>

// 初始化的代码
- (id)initWithHandler:(void (^)(id sender))handler forControlEvents:(UIControlEvents)controlEvents;

// 这里定义了事件类型和处理事件的block
@property (nonatomic) UIControlEvents controlEvents;
@property (nonatomic, copy) void (^handler)(id sender);

@end

@implementation BKControlWrapper

- (id)initWithHandler:(void (^)(id sender))handler forControlEvents:(UIControlEvents)controlEvents
{
    self = [super init];
    if (!self) return nil;

    self.handler = handler;
    self.controlEvents = controlEvents;

    return self;
}

// 该函数则是作为addTarget的SEL(@selector)参数,里面则是调用的block
- (void)invoke:(id)sender
{
    self.handler(sender);
}

@end

实现bk_addEventHandler的核心代码如下

- (void)bk_addEventHandler:(void (^)(id sender))handler forControlEvents:(UIControlEvents)controlEvents
{
    NSParameterAssert(handler);
    // 如上,在新的对象的SEL方法中调用block
    BKControlWrapper *target = [[BKControlWrapper alloc] initWithHandler:handler forControlEvents:controlEvents];
    [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents];
}

举例当监听UIButton的点击事件时

[self.menuBackgroundButton bk_addEventHandler:^(id sender) {
    @strongify(self);
    [self hideMenuAnimated:YES];
} forControlEvents:UIControlEventTouchUpInside];

很方便吧。。。

BlocksKit还有很多值得继续学习的地方,这只是一个小的方面,佩服大神

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值