iOS小技巧:用runtime 解決UIButton 重復點擊問題

參考鏈接:

http://www.cocoachina.com/ios/20150911/13260.html

問題描述:

? ? ? 我們的按鈕是點擊一次響應一次, 即使頻繁的點擊也不會出問題, 可是某些場景下還偏偏就是會出問題.

通常是如何解決

我們通常會在按鈕點擊的時候設置這個按鈕不可點擊. 等待0.xS的延時后,在設置回來; 或者在操作結(jié)束的時候設置可以點擊.


- (IBAction)clickBtn1:(UIbutton *)sender

{

sender.enabled = NO;

doSomething

sender.enabled = YES;

}


如果涉及到按鈕不同狀態(tài)不同樣式的時候, 用enabled不見得夠用.還得額外加個變量來記錄狀態(tài).


- (IBAction)clickBtn1:(UIbutton *)sender

{

if (doingSomeThing) return;

doingSomeThing = YES;

doSomething

doingSomeThing = NO;

}


上面的例子是直接在響應事件的周期內(nèi)直接禁止點擊的. 如果想做1秒內(nèi)禁止重復點擊的話,則得用performSelector:withObject:afterDelay:


漂亮的解決是怎樣的

有了重復的代碼段就是有了一個共性, 就可以抽象出來.

我們可以給按鈕添加一個屬性重復點擊間隔, 通過設置這個屬性來控制再次接受點擊事件的時間間隔.


@interface UIControl (XY)

@property (nonatomic, assign) NSTimeInterval uxy_acceptEventInterval;? // 可以用這個給重復點擊加間隔

@end

static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";

- (NSTimeInterval)uxy_acceptEventInterval

{

return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];

}

- (void)setUxy_acceptEventInterval:(NSTimeInterval)uxy_acceptEventInterval

{

objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(uxy_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}


在app啟動的時候,我們hook 所有的按鈕的 event


@implementation UIControl (XY)

+ (void)load

{

Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));

Method b = class_getInstanceMethod(self, @selector(__uxy_sendAction:to:forEvent:));

method_exchangeImplementations(a, b);

}

@end


在我們的點擊事件里呢,對點擊事件做下過濾


- (void)__uxy_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event

{

if (self.uxy_ignoreEvent) return;

if (self.uxy_acceptEventInterval > 0)

{

self.uxy_ignoreEvent = YES;

[self performSelector:@selector(setUxy_ignoreEvent:) withObject:@(NO) afterDelay:self.uxy_acceptEventInterval];

}


實際使用起來就是這個樣子


UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom];

[tempBtn addTarget:self action:@selector(clickWithInterval:) forControlEvents:UIControlEventTouchUpInside];

tempBtn.uxy_acceptEventInterval = 0.5;


雖然不推薦大范圍用runtime, 但是小范圍內(nèi)使用還是可以解決不少小問題的.

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容