THI Professional
Is life always this hard,or is it just when you are a kid?
Always like this.
在軟件開發(fā)項目中,我們經常會碰到點擊按鈕發(fā)送網絡請求,或者點擊按鈕進行頁面之間的邏輯跳轉莉掂。但是有時候遇到一些卡頓的話,用戶可能會失去耐心千扔,然后瘋狂的點擊憎妙,這時候就會多次調用按鈕觸發(fā)的方法。在某些特定的情景下會導致頁面重復push或者重復發(fā)送網絡請求曲楚。這樣的問題既對用戶體驗有影響厘唾,而且還會一定程度上增加服務器的壓力。
下面詳細講解幾種解決思路龙誊,有不完善的地方 希望大家能夠糾正抚垃。
1.在按鈕的觸發(fā)方法內部做處理
首先創(chuàng)建一個按鈕button
@interface ViewController ()
@property(nonatomic,strong)UIButton *button;
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.button = [[UIButton alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
self.button.backgroundColor = [UIColor redColor];
[self.button addTarget:self action:@selector(btnClickedOperations:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.button];
}
- (void)btnClickedOperations:(id)sender{
static NSTimeInterval time = 0.0;
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
//限制用戶點擊按鈕的時間間隔大于1秒鐘
if (currentTime - time > 1) {
//處理邏輯
NSLog(@"這是一個測試");
}
time = currentTime;
}
最終只有用戶的點擊時間間隔超過一秒鐘 才會再次調用你要處理的邏輯代碼。這樣就實現了避免用戶連續(xù)點擊按鈕帶來的影響。實現效果
2.同樣在方法內部做操作
在按鈕方法內部對按鈕的狀態(tài)進行控制 在執(zhí)行完指定的操作后 用戶才可以繼續(xù)點擊按鈕 同樣可以避免連續(xù)點擊帶來的問題 這種方法適合用在處理邏輯時間比較久的情況 鹤树,如果處理邏輯時間很短暫 那么就起不到限制用戶連續(xù)點擊的情況
- (void)test:(UIButton *)btn{
btn.enabled = NO;
//處理邏輯
btn.enabled = YES;
}
如果想控制按鈕的時間間隔同樣可以加一個延遲的方法
- (void)test:(UIButton *)btn{
btn.enabled = NO;
//處理邏輯
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"btnClickedOperations");
btn.enabled = YES;
});
}
實現效果
[圖片上傳中...(屏幕快照 2017-11-16 上午10.15.17.png-86dc45-1510798532321-0)]
屏幕快照 2017-11-16 上午9.53.55.png
第三種:使用runtime铣焊,一勞永逸我這設的是0.5秒內不會被重復點擊
#import <UIKit/UIKit.h>
@interface UIControl (repeatedClick)
/**
可以重復點擊的時間間隔
默認為0 不對按鈕重復點擊處理
*/
@property (nonatomic,assign) NSTimeInterval timeInterval;//用這個給重復點擊加間隔
/**
內部屬性用于判斷是否忽略替換的點擊事件
*/
@property (nonatomic,assign) BOOL isIgnoreEvent;
@end
#import "UIControl+repeatedClick.h"
#import <objc/runtime.h>
#define defaultInterval 0//默認時間間隔 0.25
@implementation UIControl (repeatedClick)
- (NSTimeInterval)timeInterval{
return [objc_getAssociatedObject(self,_cmd)doubleValue];
}
- (void)setTimeInterval:(NSTimeInterval)timeInterval{
objc_setAssociatedObject(self,@selector(timeInterval),@(timeInterval),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (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的實現添加到系統(tǒng)方法中也就是說將methodA方法指針添加成方法methodB的返回值表示是否添加成功
BOOL isAdd = class_addMethod(self, selA,method_getImplementation(methodB),method_getTypeEncoding(methodB));
//添加成功了說明本類中不存在methodB所以此時必須將方法b的實現指針換成方法A的,否則b方法將沒有實現魂迄。
if(isAdd) {
class_replaceMethod(self, selB,method_getImplementation(methodA),method_getTypeEncoding(methodA));
}else{
//添加失敗了說明本類中有methodB的實現粗截,此時只需要將methodA和methodB的IMP互換一下即可。
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 ? defaultInterval:self.timeInterval;
if(self.isIgnoreEvent){
return;
}else if(self.timeInterval > 0){
[self performSelector:@selector(resetState)withObject:nil afterDelay:self.timeInterval];
}
}
//此處methodA和methodB方法IMP互換了捣炬,實際上執(zhí)行sendAction熊昌;所以不會死循環(huán)
self.isIgnoreEvent = YES;
[self mySendAction:action to:target forEvent:event];
}
@end
以上就是處理按鈕連續(xù)點擊問題的解決辦法,希望能對你有所幫助湿酸,文章中的代碼已經上傳到github.