我在应用程序中有一个UIButton
,允许用户向API发送请求。
如何防止用户每秒按下此按钮超过 X 次?
我假设如果点击按钮太频繁,您想忽略按钮,但您无需将按钮设置为在忽略点击时显示为禁用。(如果要更改按钮外观,则需要使用NSTimer
或其他延迟操作来重新启用按钮,这是一个非常复杂的问题。
如果将要求更改为"两次点击之间至少 1/X 秒",那就简单了一点。例如,如果点击时间在上一次点击后不到 1/4 秒,我们将忽略该点击,而不是每秒最多允许 4 次点击。
要实现此要求,请存储上次点击的时间。当点击到达时,查看自上次点击以来是否已经过去了 1/X 秒。如果没有,请忽略水龙头。
private let minimumTapInterval = 1 / CFTimeInterval(4)
private var lastTapTime = CFAbsoluteTime(0)
@IBAction func buttonWasTapped(sender: AnyObject?) {
let now = CFAbsoluteTimeGetCurrent()
guard now >= lastTapTime + minimumTapInterval else { return }
lastTapTime = now
sendAPIRequest()
}
如果您确实要实现"每秒不超过 X 次点击"的要求,您可以存储接受的点击次数。当新的水龙头进来时,扔掉任何超过一秒的存储时间。如果仍有至少 X 个存储时间,请忽略新点击。
private let maxTapsPerSecond = 4
private var tapTimes = [CFAbsoluteTime]()
@IBAction func buttonWasTapped(sender: AnyObject?) {
let now = CFAbsoluteTimeGetCurrent()
let oneSecondAgo = now - 1
tapTimes = tapTimes.filter { $0 >= oneSecondAgo }
// All elements of tapTimes are now within the last second.
guard tapTimes.count < maxTapsPerSecond else { return }
tapTimes.append(now)
sendAPIRequest
}
UIButton
的isEnabled
属性。对于按钮的目标,请在@objc
选择器函数的末尾添加以下内容:
@objc func handleMyButtonPress() {
self.someOtherFunction()
myButton.isEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
myButton.isEnabled = true
}
}
.now() + 1
截止日期基本上是说,1 秒后按钮将再次启用,您的用户可以与之交互。
对于 5 分钟的延迟,您可以使用.now() + (60 * 5)
我自己使用它,它几乎在任何情况下都能可靠地工作。
希望这个答案可以帮助您或其他人解决同样的问题。