場景
當(dāng)app有點(diǎn)卡的時(shí)候闰蛔,多次點(diǎn)擊相同的button悟泵,經(jīng)常出現(xiàn),跳轉(zhuǎn)了N次相同的界面
解決辦法
用運(yùn)行時(shí)和分類,替換UIControl
響應(yīng)事件干旁,根據(jù)響應(yīng)的間隔時(shí)間來判斷是否執(zhí)行事件驶沼。
另一種解決方案就是button點(diǎn)擊事件執(zhí)行時(shí)設(shè)置button的用戶交互屬性,再次只討論設(shè)置兩次點(diǎn)擊間隔的問題争群。
詳細(xì)步驟
創(chuàng)建一個(gè)UIControl
的分類
為了方便他人調(diào)整不同的間隔時(shí)間需求,在UIControl+Custom.h
文件中開放間隔時(shí)間屬性大年,UIControl+Custom.h
文件的代碼為:
<pre><code>
import <UIKit/UIKit.h>
@interface UIControl (Custom)
@property (nonatomic, assign) NSTimeInterval custom_acceptEventInterval;// 可以用這個(gè)給重復(fù)點(diǎn)擊加間隔
@end
</pre></code>
在UIControl+Custom.m
文件中實(shí)現(xiàn)方法交換(妥善的做法是:先添加方法换薄,如果方法已經(jīng)存在,就替換原方法)翔试,在UIControl+Custom.m
文件的代碼為:
<pre><code>
import "UIControl+custom.h"
import <objc/runtime.h>
@interface UIControl()
@property (nonatomic, assign) NSTimeInterval custom_acceptEventTime;
@end
@implementation UIControl (Custom)
+ (void)load{
Method systemMethod = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
SEL sysSEL = @selector(sendAction:to:forEvent:);
Method customMethod = class_getInstanceMethod(self, @selector(custom_sendAction:to:forEvent:));
SEL customSEL = @selector(custom_sendAction:to:forEvent:);
//添加方法 語法:BOOL class_addMethod(Class cls, SEL name, IM P imp, const char *types) 若添加成功則返回No
// cls:被添加方法的類 name:被添加方法方法名 imp:被添加方法的實(shí)現(xiàn)函數(shù) types:被添加方法的實(shí)現(xiàn)函數(shù)的返回值類型和參數(shù)類型的字符串
BOOL didAddMethod = class_addMethod(self, sysSEL, method_getImplementation(customMethod), method_getTypeEncoding(customMethod));
//如果系統(tǒng)中該方法已經(jīng)存在了轻要,則替換系統(tǒng)的方法 語法:IMP class_replaceMethod(Class cls, SEL name, IMP imp,const char *types)
if (didAddMethod) {
class_replaceMethod(self, customSEL, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
}else{
method_exchangeImplementations(systemMethod, customMethod);
}
}
- (NSTimeInterval )custom_acceptEventInterval{
return [objc_getAssociatedObject(self, "UIControl_acceptEventInterval") doubleValue];
}
- (void)setCustom_acceptEventInterval:(NSTimeInterval)custom_acceptEventInterval{
objc_setAssociatedObject(self, "UIControl_acceptEventInterval", @(custom_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSTimeInterval )custom_acceptEventTime{
return [objc_getAssociatedObject(self, "UIControl_acceptEventTime") doubleValue];
}
- (void)setCustom_acceptEventTime:(NSTimeInterval)custom_acceptEventTime{
objc_setAssociatedObject(self, "UIControl_acceptEventTime", @(custom_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)custom_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
// 如果想要設(shè)置統(tǒng)一的間隔時(shí)間,可以在此處加上以下幾句
// 值得提醒一下:如果這里設(shè)置了統(tǒng)一的時(shí)間間隔垦缅,會影響UISwitch,如果想統(tǒng)一設(shè)置冲泥,又不想影響UISwitch,建議將UIControl分類壁涎,改成UIButton分類凡恍,實(shí)現(xiàn)方法是一樣的
// if (self.custom_acceptEventInterval <= 0) {
// // 如果沒有自定義時(shí)間間隔,則默認(rèn)為2秒
// self.custom_acceptEventInterval = 2;
// }
// 是否小于設(shè)定的時(shí)間間隔
BOOL needSendAction = (NSDate.date.timeIntervalSince1970 - self.custom_acceptEventTime >= self.custom_acceptEventInterval);
// 更新上一次點(diǎn)擊時(shí)間戳
if (self.custom_acceptEventInterval > 0) {
self.custom_acceptEventTime = NSDate.date.timeIntervalSince1970;
}
// 兩次點(diǎn)擊的時(shí)間間隔小于設(shè)定的時(shí)間間隔時(shí)怔球,才執(zhí)行響應(yīng)事件
if (needSendAction) {
[self custom_sendAction:action to:target forEvent:event];
}
}
@end
</pre></code>
簡書的一次試水嚼酝,文章參考自簡書ocarol