用戶快速點擊某個按鈕,導致頁面重複push或者重複發送網絡請求。這樣的問題既對用戶體驗有影響,而且還會一定程度上增加服務器的壓力。
主要使用以下辦法:
1、在每次點擊時先取消之前的操作
- (void)buttonClicked:(id)sender
{
//這裏是關鍵,點擊按鈕後先取消之前的操作,再進行需要進行的操作
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(buttonClicked:) object:sender];
[self performSelector:@selector(buttonClicked: )withObject:sender afterDelay:0.2f];
}
2、點擊後將按鈕置爲不可點擊狀態,幾秒後恢復
-(void)buttonClicked:(id)sender{
self.button.enabled = NO;
[self performSelector:@selector(changeButtonStatus) withObject:nil afterDelay:1.0f];//防止用戶重複點擊
}
-(void)changeButtonStatus{
self.button.enabled = YES;
}
3、利用運行時
// UIControl+Custom.h
// Created by ocarol on 16/8/16.
// Copyright © 2016年 ocarol. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIControl (Custom)
@property (nonatomic, assign) NSTimeInterval custom_acceptEventInterval;// 可以用這個給重複點擊加間隔
@end
在 UIControl+Custom.m 文件中實現方法交換(妥善的做法是:先添加方法,如果方法已經存在,就替換原方法),在 UIControl+Custom.m 文件的代碼爲:
// UIControl+Custom.m
// Created by ocarol on 16/8/16.
// Copyright © 2016年 ocarol. All rights reserved.
//
#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, IMP imp, const char *types) 若添加成功則返回No
// cls:被添加方法的類 name:被添加方法方法名 imp:被添加方法的實現函數 types:被添加方法的實現函數的返回值類型和參數類型的字符串
BOOL didAddMethod = class_addMethod(self, sysSEL, method_getImplementation(customMethod), method_getTypeEncoding(customMethod));
//如果系統中該方法已經存在了,則替換系統的方法 語法: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{
// 如果想要設置統一的間隔時間,可以在此處加上以下幾句
// 值得提醒一下:如果這裏設置了統一的時間間隔,會影響UISwitch,如果想統一設置,又不想影響UISwitch,建議將UIControl分類,改成UIButton分類,實現方法是一樣的
// if (self.custom_acceptEventInterval <= 0) {
// // 如果沒有自定義時間間隔,則默認爲2秒
// self.custom_acceptEventInterval = 2;
// }
// 是否小於設定的時間間隔
BOOL needSendAction = (NSDate.date.timeIntervalSince1970 - self.custom_acceptEventTime >= self.custom_acceptEventInterval);
// 更新上一次點擊時間戳
if (self.custom_acceptEventInterval > 0) {
self.custom_acceptEventTime = NSDate.date.timeIntervalSince1970;
}
// 兩次點擊的時間間隔小於設定的時間間隔時,才執行響應事件
if (needSendAction) {
[self custom_sendAction:action to:target forEvent:event];
}
}
@end
使用舉例:
UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[tempBtn addTarget:self action:@selector(clickWithInterval:) forControlEvents:UIControlEventTouchUpInside];
tempBtn.uxy_acceptEventInterval = 0.5;