「iOS造*」之UIButton 用Block响应事件

时间:2022-06-01 18:20:53

俗语说 一个不懒的程序员不是好程序员

造*,也只是为了以后更好的coding。

coding,简易明了的代码更是所有程序员都希望看到的

无论是看自己的代码,还是接手别人的代码 都希望一看都知道这代码是干嘛的。。

UI开发中用得最多的控件之一的UIButton,大家都知道其继承于UIControl,即带响应事件的UIView

点击事件的添加大家都知道是通过

    [buttonObj addTarget:target action:SEL forControlEvents:controlEvents];

这么一句代码来实现,在SEL中选择的方法响应

后面编码为了代码看上去好看一点(偷懒) 改成了Block式响应

这个Block响应会在什么时候使用呢?如果处理的内容比较简单的话是无妨的,而且不需要作为外部方法被调用

实际上是这样的

「iOS造*」之UIButton 用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,对应响应即可