? ? 在開發(fā)的實際過程中阶牍,我們會發(fā)現(xiàn)UIButton的觸發(fā),可能會因為用戶的高速連續(xù)點擊而被觸發(fā)多次星瘾。在實際的場景化服務中走孽,肯能這并不是我們想要的。我們更傾向于給按鈕設置一個響應間隔時間琳状。由此引發(fā)了磕瓷,下列的思考。
1念逞、改變button的enable狀態(tài)困食,再點擊后的一段時間內置為NO;
-(void)buttonClick:(UIButton *)btn
{
? ? self.btn.enabled = NO;
? ? [btn performSelector:@selector(changeBtnEnable) withObject:nil afterDelay:1.0f];
}
- (void)changeBtnEnable
{
? ? self.btn.enable = YES;
}
2翎承、鑒于第一種方法過于繁瑣硕盹,且每個button都要重復設置,所以摒棄這種做法叨咖。直接寫一個UIButtonde分類瘩例。
.h文件
#import <objc/runtime.h>//倒入runtime
@interface UIButton (NoClickTwo)
@property (nonatomic , assign) NSTimeInterval timeInterval;
@property (nonatomic , assign) BOOL? ? isIgnoreEvent;//YES不允許點擊NO允許點擊
@end
.m文件實現(xiàn)
@implementation UIButton (NoClickTwo)
- (NSTimeInterval)timeInterval
{
? ? return [objc_getAssociatedObject(self, _cmd) doubleValue];
}
- (void)setTimeInterval:(NSTimeInterval)timeInterval
{
? ? objc_setAssociatedObject(self, @selector(timeInterval), @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//runtime動態(tài)綁定屬性
- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent
{
? ? objc_setAssociatedObject(self, @selector(isIgnoreEvent), @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isIgnoreEvent
{
? ? return [objc_getAssociatedObject(self, _cmd) boolValue];
}
- (void)resetState
{
? ? [self setIsIgnoreEvent:NO];
}
+ (void)load
{
? ? static dispatch_once_t onceToken;
? ? dispatch_once(&onceToken, ^{
? ? ? ? SEL selA = @selector(sendAction:to:forEvent:);
? ? ? ? SEL selB = @selector(mySendAction:to:forEvent:);
? ? ? ? Method methodA = class_getInstanceMethod(self, selA);
? ? ? ? Method methodB = class_getInstanceMethod(self,selB);
? ? ? ? /*
? ? ? ? *將methodB的實現(xiàn)添加到系統(tǒng)方法中
? ? ? ? *也就是說將methodA方法指針添加成方法methodB
? ? ? ? *返回值表示是否添加成功
? ? ? ? */
? ? ? ? BOOL isAdd = class_addMethod(self, selA, method_getImplementation(methodB), method_getTypeEncoding(methodB));
? ? ? ? //添加成功了說明本類中不存在methodB 啊胶,所以此時必須將方法b的實現(xiàn)指針換成方法A的,否則b方法將沒有實現(xiàn)
? ? ? ? if (isAdd) {
? ? ? ? ? ? class_replaceMethod(self, selB, method_getImplementation(methodA), method_getTypeEncoding(methodA));
? ? ? ? }else{
? ? ? ? ? ? //添加失敗了說明本類中有methodB的實現(xiàn)垛贤,此時只需要將methodA和methodB的函數(shù)指針互換一下即可焰坪。
? ? ? ? ? ? method_exchangeImplementations(methodA, methodB);
? ? ? ? }
? ? });
}
- (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
? ? if ([NSStringFromClass([self class]) isEqualToString:@"UIButton"]) {
? ? ? ? self.timeInterval = self.timeInterval == 0? 1.0f:self.timeInterval;
? ? ? ? if (self.isIgnoreEvent) {
? ? ? ? ? ? return;
? ? ? ? }else if(self.timeInterval > 0 ){
? ? ? ? ? ? [self performSelector:@selector(resetState)
? ? ? ? ? ? ? ? ? ? ? withObject:nil
? ? ? ? ? ? ? ? ? ? ? afterDelay:self.timeInterval];
? ? ? ? }
? ? }
? ? self.isIgnoreEvent = YES;
? ? //此處methodA和methodB方法IMP互換了,實際上執(zhí)行sendAction南吮;所以不會死循環(huán)
? ? [self mySendAction:action to:target forEvent:event];
}
@end