iOS UIButton按钮防止重复点击
2021-09-27 本文已影响0人
ufogxl
开发app过程中我们经常会遇到按钮多次重复点击后出现不想看到的情况,比如多次push到下一个页面,多次添加到同一个数据等,这时我们就要考虑在点击后,能够限制用户继续点击这个按钮。
比较常见的解决有以下几种:
一、在点击事件中将按钮的isEnabled设置为false,确认可以再次点击再改回true
@objc func tapButton(button:UIButton){
button.isEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 2){
button.isEnabled = true;
}
}
二、给当前页面设置loading蒙版,比如使用SVProgressHUD:
@objc func tapButton(button:UIButton){
SVProgressHUD.show()
DispatchQueue.main.asyncAfter(deadline: .now() + 2){
SVProgressHUD.dismiss()
}
}
三、使用方法交换,给按钮的的点击设置时间间隔
这里交换的是UIButton.sendAction(_:to:for:)方法
1.新增时间间隔控制关联对象
let isEventUnavailableKey = "isEventUnavailableKey"
let eventIntervalKey = "eventIntervalKey"
extension UIButton{
//事件间隔
var eventInterval: TimeInterval {
get {
return (objc_getAssociatedObject(self, &UIButtonKey.eventIntervalKey) as? TimeInterval) ?? 0
}
set {
objc_setAssociatedObject(self, &UIButtonKey.eventIntervalKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
//是否可用标志
var isEventUnavailable: Bool {
get {
return (objc_getAssociatedObject(self, &UIButtonKey.isEventUnavailableKey) as? Bool) ?? false
}
set {
objc_setAssociatedObject(self, &UIButtonKey.isEventUnavailableKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
2.新增点击事件方法
@objc func intervalSendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
if isEventUnavailable == false {
isEventUnavailable = true
mySendAction(action, to: target, for: event)
perform(#selector(setIsEventUnavailable(_: )), with: false, afterDelay: eventInterval)
}
}
3.方法交换
extension UIButton{
static let once:Void = {
exchange()
}()
static func exchange(){
let original = #selector(UIButton.sendAction(_:to:for:))
let swizzled = #selector(UIButton.sendAction .intervalSendAction(_:to:for:))
guard let originalMethod = class_getInstanceMethod(UIButton.self, original),
let swizzledMethod = class_getInstanceMethod(UIButton.self, swizzled) else {
return
}
let didAddMethod = class_addMethod(UIButton.self, original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(UIButton.self, swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
4.最后在按钮被点击之前(如app入口)处调用方法交换
UIButton.once
5.给按钮设置间隔
button.eventInterval = 2
----------完成-----------