前言
我又来偷懒来了,
UIButton同样也是我们经常使用到的控件,那么常规我们为按钮绑定点击事件都是写一个方法,然后绑定这样子,一如既往我还是比较喜欢东西放在一起找起来也方便,于是有了下面的封装处理 之前写过一篇UIView的手势点击,这两基本就解决了大部分常规的点击处理
iOS UIView添加手势回调 . 将偷懒进行到底 - -|
. Demo地址
API
/// 添加点击事件,默认UIControlEventTouchUpInside - (void)kj_addAction:(KJButtonBlock)block; /// 添加事件,不支持多枚举形式 - (void)kj_addAction:(KJButtonBlock)block forControlEvents:(UIControlEvents)controlEvents;
常规对比
常规做法
[_button addTarget:self action:@selector(action) forControlEvents:(UIControlEventTouchUpInside)]; [_button addTarget:self action:@selector(action2) forControlEvents:(UIControlEventTouchDown)]; /// Action - (void)action{ NSLog(@"UIControlEventTouchUpInside"); } - (void)action2{ NSLog(@"UIControlEventTouchDown"); }
封装之后做法
[_button kj_addAction:^(UIButton * _Nonnull kButton) { NSLog(@"UIControlEventTouchUpInside"); }]; [_button kj_addAction:^(UIButton * _Nonnull kButton) { NSLog(@"UIControlEventTouchDown"); } forControlEvents:(UIControlEventTouchDown)];
------- 🎈 给我点赞 🎈 ------- 编译时间:16:51:45 文件名:KJButtonVC.m 方法名:-[KJButtonVC button]_block_invoke_2 行号:128 打印信息:UIControlEventTouchDown ------- 🎈 给我点赞 🎈 ------- 编译时间:16:51:45 文件名:KJButtonVC.m 方法名:-[KJButtonVC button]_block_invoke 行号:125 打印信息:UIControlEventTouchUpInside
简单介绍
1. 暂时支持UIControlEvents
九种类型
static NSString * const _Nonnull KJButtonControlEventsStringMap[] = { [UIControlEventTouchDown] = @"KJ_X_UIControlEventTouchDown", [UIControlEventTouchDownRepeat] = @"KJ_X_UIControlEventTouchDownRepeat", [UIControlEventTouchDragInside] = @"KJ_X_UIControlEventTouchDragInside", [UIControlEventTouchDragOutside] = @"KJ_X_UIControlEventTouchDragOutside", [UIControlEventTouchDragEnter] = @"KJ_X_UIControlEventTouchDragEnter", [UIControlEventTouchDragExit] = @"KJ_X_UIControlEventTouchDragExit", [UIControlEventTouchUpInside] = @"KJ_X_UIControlEventTouchUpInside", [UIControlEventTouchUpOutside] = @"KJ_X_UIControlEventTouchUpOutside", [UIControlEventTouchCancel] = @"KJ_X_UIControlEventTouchCancel", };
2. 事件响应方法处理
我喜欢偷懒所以采用宏的方式处理
#define KJButtonAction(name) \ - (void)kj_action##name{ \ KJButtonBlock block = objc_getAssociatedObject(self, _cmd);\ if (block) block(self);\ } /// 事件响应方法 KJButtonAction(KJ_X_UIControlEventTouchDown); KJButtonAction(KJ_X_UIControlEventTouchDownRepeat); KJButtonAction(KJ_X_UIControlEventTouchDragInside); KJButtonAction(KJ_X_UIControlEventTouchDragOutside); KJButtonAction(KJ_X_UIControlEventTouchDragEnter); KJButtonAction(KJ_X_UIControlEventTouchDragExit); KJButtonAction(KJ_X_UIControlEventTouchUpInside); KJButtonAction(KJ_X_UIControlEventTouchUpOutside); KJButtonAction(KJ_X_UIControlEventTouchCancel);
3. kj_addAction:forControlEvents:
事件处理
/// 添加点击事件,默认UIControlEventTouchUpInside - (void)kj_addAction:(KJButtonBlock)block{ [self kj_addAction:block forControlEvents:UIControlEventTouchUpInside]; } /// 添加事件 - (void)kj_addAction:(KJButtonBlock)block forControlEvents:(UIControlEvents)controlEvents{ if (block == nil || controlEvents>(1<<8)) return; if (controlEvents != UIControlEventTouchDown && (controlEvents&1)) return; NSString *actionName = [@"kj_action" stringByAppendingFormat:@"%@",KJButtonControlEventsStringMap[controlEvents]]; SEL selector = NSSelectorFromString(actionName); objc_setAssociatedObject(self, selector, block, OBJC_ASSOCIATION_COPY_NONATOMIC); [self addTarget:self action:selector forControlEvents:controlEvents]; }
分别说说三种return的情况
block
:回调未处理
controlEvents>(1<<8)
:超出九种情况
controlEvents&1
:多枚举情况
4. 获取每种UIControlEvents
对应的绑定方法
NSString *actionName = [@"kj_action" stringByAppendingFormat:@"%@",KJButtonControlEventsStringMap[controlEvents]]; SEL selector = NSSelectorFromString(actionName);
5. 回调和绑定方法
objc_setAssociatedObject(self, selector, block, OBJC_ASSOCIATION_COPY_NONATOMIC); [self addTarget:self action:selector forControlEvents:controlEvents];
6. 获取回调处理
获取每种方法对应的回调
KJButtonBlock block = objc_getAssociatedObject(self, _cmd); if (block) block(self);
友情提醒
暂时我只封装了上述的九种点击方式,其余的暂未处理
暂时不支持多枚举,例如如下方式是不支持的
[_button kj_addAction:^(UIButton * _Nonnull kButton) { NSLog(@"UIControlEventTouchDown"); } forControlEvents:(UIControlEventTouchDown)|(UIControlEventTouchUpInside)];