我希望在按钮成功按下后,能够防止它在一段时间内被再次按下。
我的第一个想法是使用一个计时器,在一定的时间内禁用按钮,但我不确定如何实现这一点。
请问有人可以指点我正确的方向吗?
我正在使用Swift语言。
不需要计时器。不需要禁用。
当按钮被点击时,将当前日期存储在实例属性中。当再次点击按钮时,在将当前日期存储在同一实例属性之前,从旧日期中减去新日期。如果它们太接近,则不执行按钮的任何操作。
换句话说,只有两个时间戳足够远才会采取行动。
这称为去抖动,是一种常见的技术。搜索一下,你会在这里找到很多关于它的讨论。
编辑:现在不需要日期存储!只需使用组合框架内置的debounce
运算符即可。
我认为这个扩展很方便:
extension UIButton {
func preventRepeatedPresses(inNext seconds: Double = 1) {
self.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds) {
self.isUserInteractionEnabled = true
}
}
}
@IBAction func pressedButton(_ sender: UIButton) {
sender.preventRepeatedPresses()
// do the job
}
var ButtonIsActiv = false
func buttonPressed(button: UIButton) {
if ButtonIsActiv == false {
// do something with your button
ButtonIsActiv = true
// after 3 seconds, activate it again
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
ButtonIsActiv = false
}
} else {
// your button is not activated
}
}
//
// ViewController.swift
// SwiftButtonStopStackOverflow
//
// Created by Seoksoon Jang on 29/09/2016.
// Copyright © 2016 Seoksoon Jang. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet var testButton: UIButton!
@IBAction func clickAction(_ sender: AnyObject) {
self.testButton.isEnabled = !self.testButton.isEnabled
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.testButton.isEnabled = !self.testButton.isEnabled
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
你可以在控制器中设置一个布尔值,表示按钮是否可操作。当按钮被按下时,设置布尔值,并安排一个时间间隔,如下所示:
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(<YourMethod>), userInfo: nil, repeats: false)
另一种策略是,在按钮被按下后,禁用属性userInteractionEnabled
的交互,然后使用计时器再次启用该属性。
extension UIButton {
override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
self.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.isUserInteractionEnabled = true
}
}
}
如果您有一些需要反复点击的按钮,您可以使用特定的扩展类来处理这些特殊的按钮,或者为所有按钮创建一个自定义的扩展类,并使用@IBInspectable
类型为Bool
的属性来设置是否在按下某个特定按钮后暂时禁用它。