「iOS造轮子」之UIButton 用Block响应事件
俗语说 一个不懒的程序员不是好程序员
造轮子,也只是为了以后更好的coding。
coding,简易明了的代码更是所有程序员都希望看到的
无论是看自己的代码,还是接手别人的代码 都希望一看都知道这代码是干嘛的。。
UI开发中用得最多的控件之一的UIButton,大家都知道其继承于UIControl,即带响应事件的UIView
点击事件的添加大家都知道是通过
[buttonObj addTarget:target action:SEL forControlEvents:controlEvents];
这么一句代码来实现,在SEL中选择的方法响应
后面编码为了代码看上去好看一点(偷懒) 改成了Block式响应
这个Block响应会在什么时候使用呢?如果处理的内容比较简单的话是无妨的,而且不需要作为外部方法被调用
实际上是这样的
上面注释掉的是原来添加响应的方式,下面则是block式响应
有个不好的是要处理好循环引用的问题
增加block式响应 步骤如下
首先建立UIButton的Category
添加 实例方法
- (void)addActionBlock:(void(^)())block forControlEvents:(UIControlEvents)controlEvents;
这里的Block 大家可以根据需要来加入回调参数,都是随大家的。。
然后再加入存放Block的Property
@property (copy,nonatomic) void(^actionBlock)();
显然,在Category下无法直接添加Property,这里又需要通过Runtime来做相应的设置了:
在.m中,引入
objc/runtime.h
并实现set和get方法
- (void)setActionBlock:(void (^)())actionBlock{ objc_setAssociatedObject(self, @selector(actionBlock), actionBlock, OBJC_ASSOCIATION_COPY); } - (void (^)())actionBlock{ return objc_getAssociatedObject(self, _cmd); }
然后实现刚声明的addActionBlock方法
- (void)addActionBlock:(void(^)())block forControlEvents:(UIControlEvents)controlEvents{ self.actionBlock = [block copy]; /** 将方法中的Block拿下 */ [self addTarget:self action:@selector(__startAction:) forControlEvents:controlEvents]; /** 添加一个事件 */ }
响应:
- (void)__startAction:(UIButton *)sender{ if (self.actionBlock) self.actionBlock(); }
这就完成了一个事件的响应
后面就可以直接通过
- (void)addActionBlock:(void(^)())block forControlEvents:(UIControlEvents)controlEvents;
来添加这个响应事件了
但是 请注意
由于property中的block 只有1个!!!在设置多个event的时候,原来设置的block会被覆盖
那么这种情况该如何解决呢?
傻瓜一点的方法:
不同event分别添加不同的action和block,对应响应即可