UIButton的防连点类扩展:
1.原理: 尽管swift不像OC那样是纯运行时语言,但是swift中继承自NSObject的类是可以使用runtime的,显然UIButton符合这一点,所以说在swift中UIButton也是可以使用runtime来解决连点问题的,话不多说直接上代码:
import UIKit
public extension UIButton {
private struct cs_associatedKeys {
static var accpetEventInterval = "cs_acceptEventInterval"
static var acceptEventTime = "cs_acceptEventTime"
}
/**
重复点击的时间间隔--自己手动随意设置
利用运行时机制 将accpetEventInterval值修改
*/
var cs_accpetEventInterval: TimeInterval {
get {
if let accpetEventInterval = objc_getAssociatedObject(self, &cs_associatedKeys.accpetEventInterval) as? TimeInterval {
return accpetEventInterval
}
return 1.0
}
set {
objc_setAssociatedObject(self, &cs_associatedKeys.accpetEventInterval, newValue as TimeInterval, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
/**
重复点击的时间间隔--自己手动随意设置
利用运行时机制 将acceptEventTime值修改
*/
var cs_acceptEventTime : TimeInterval {
get {
if let acceptEventTime = objc_getAssociatedObject(self, &cs_associatedKeys.acceptEventTime) as? TimeInterval {
return acceptEventTime
}
return 1.0
}
set {
objc_setAssociatedObject(self, &cs_associatedKeys.acceptEventTime, newValue as TimeInterval, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
/**
重写初始化方法,在这个方法中实现在运行时方法替换
*/
override open class func initialize() {
let changeBefore: Method = class_getInstanceMethod(self, #selector(UIButton.sendAction(_:to:for:)))
let changeAfter: Method = class_getInstanceMethod(self, #selector(UIButton.cs_sendAction(action:to:for:)))
method_exchangeImplementations(changeBefore, changeAfter)
}
/**
在这个方法中判断接收到当前事件的时间间隔是否满足我们所设定的间隔,会一直循环调用到满足才会return
*/
func cs_sendAction(action: Selector, to target: AnyObject?, for event: UIEvent?) {
if NSDate().timeIntervalSince1970 - self.cs_acceptEventTime < self.cs_accpetEventInterval {
return
}
if self.cs_accpetEventInterval > 0 {
self.cs_acceptEventTime = NSDate().timeIntervalSince1970
}
self.cs_sendAction(action: action, to: target, for: event)
}
}
以上就是这个扩展中的所有代码,可以直接使用哟(注:这个是swift3.0语法写的,3.0以下版本需要自己稍微修改),有什么疑问欢迎一起去探讨学习!
网友评论
有个不明白的地方, 是不是写了这个分类之后,所有的按钮都会被限制了点击速度?
如果有的按钮想让他快速点击怎么办