前言
- 我又來偷懶來了,
- UIButton同樣也是我們經常使用到的控件,那麼常規我們爲按鈕綁定點擊事件都是寫一個方法,然後綁定這樣子,一如既往我還是比較喜歡東西放在一起找起來也方便,於是有了下面的封裝處理
之前寫過一篇UIView的手勢點擊,這兩基本就解決了大部分常規的點擊處理
iOS UIView添加手勢回調 . 將偷懶進行到底 - -|
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)];