經常會遇到重復點擊某個按鈕 事件被響應多次的情景, 有時候可能對程序本身並沒有什么影響 , 可有時候偏偏需要限制button響應事件直接的間隔 .
方法一 : 標記
1 . 利用空閑enable屬性來標記
1 - (IBAction)clickBtn1:(UIbutton *)sender 2 { 3 sender.enabled = NO; 4 doSomething 5 sender.enabled = YES; 6 }
2. 專門定義一個屬性標記
1 - (IBAction)clickBtn1:(UIbutton *)sender 2 { 3 if (doingSomeThing) return; 4 doingSomeThing = YES; 5 doSomething 6 doingSomeThing = NO; 7 }
方法二 : 利用runtime來實現
和前一種方法的實現原理基本一樣 只不過通過給UIControl 添加分類 由此擴大了應用范圍
首先給按鈕條件一個屬性 記錄目標間隔時間
1 @interface UIControl (MYButton) 2 @property (nonatomic, assign) NSTimeInterval my_acceptEventInterval; // 可以用這個給重復點擊加間隔 3 @end 4 static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval"; 5 - (NSTimeInterval)my_acceptEventInterval 6 { 7 return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue]; 8 } 9 - (void)setMy_acceptEventInterval:(NSTimeInterval)my_acceptEventInterval 10 { 11 objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(my_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 12 }
//交換系統的方法
1 @implementation UIControl (MYButton) 2 + (void)load 3 { 4 Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:)); 5 Method b = class_getInstanceMethod(self, @selector(__my_sendAction:to:forEvent:)); 6 method_exchangeImplementations(a, b); 7 } 8 @end
//定義自己的點擊事件
1 - (void)__my_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event 2 { 3 if (self.my_ignoreEvent) return; 4 if (self.my_acceptEventInterval > 0) 5 { 6 self.my_ignoreEvent = YES; 7 [self performSelector:@selector(setMy_ignoreEvent:) withObject:@(NO) afterDelay:self.my_acceptEventInterval]; 8 } 9 [self __my_sendAction:action to:target forEvent:event]; 10 }
實際使用起來就是這個樣子
1 UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 2 [tempBtn addTarget:self action:@selector(clickWithInterval:) forControlEvents:UIControlEventTouchUpInside]; 3 tempBtn.uxy_acceptEventInterval = 0.5;
一個應用Runtime 的小小實例