【问题标题】:Disable a button for 30 seconds when pressed, enable again, then disabled when pressed again按下时禁用按钮 30 秒,再次启用,然后再次按下时禁用
【发布时间】:2021-09-10 06:30:13
【问题描述】:

我正在努力完成这项工作。我想要一个按钮,一旦按下一定时间就会被禁用。一旦该时间结束,该按钮将再次启用,直到再次按下它,然后在设定的时间内禁用它。我不希望通过重新启动应用程序轻松再次启用该按钮。它必须保持禁用状态,直到时间结束,而不是直到应用程序的下一次启动.. 到目前为止,我的代码只能禁用按钮一次。它不起作用,在时间过去后再次启用它。在我重新启动应用程序后,该按钮也再次启用。这是不应该发生的。

任何人有一个想法,我怎样才能让它按照我想要的方式工作?

这是我的代码:

button.isUserInteractionEnabled = false
Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { _ in
    button.isUserInteractionEnabled = false
})

我也试过这样:

_ = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fireTimer), userInfo: nil, repeats: true)
_ = Timer.scheduledTimer(timeInterval: 0.0, target: self, selector: #selector(fireTimer2), userInfo: nil, repeats: false)

@objc 是:

@objc func fireTimer() {
    print("Timer fired!")
}

@objc func fireTimer2() {
    print("Start timer.")
}

我想尝试一下,如果我可以设置开始时间和重复时间,希望通过按钮让事情顺利进行。我没有。 谁能帮帮我?

非常感谢!万事如意

更新,6 月 29 日:

这是代码,我用于我的按钮并使我想要的禁用/启用功能起作用。

 @objc private let actionButton: UIButton = {
   let button = UIButton()
    button.setTitle("Button Title", for: .normal)
    button.titleLabel?.font = UIFont(name: "Times New Roman", size: 16)
    button.setTitleColor(.secondaryLabel, for: .normal)

    button.addTarget(self, action: #selector(didTapButton), for: .touchDown)

return button
}()

@objc func didTapButton() {
self.actionButton.isUserInteractionEnabled = false
Timer.scheduledTimer(withTimeInterval: 20, repeats: true) { _ in
    self.actionButton.isUserInteractionEnabled = true
}}

那么如何将计时器中的数据存储在core data(???) 或UserDefaults(???) 或其他任何地方,以便在重新启动应用程序时计时器不会重置?

【问题讨论】:

  • 您是否尝试向UserDefaults 添加时间,您的计时器/初始化方法可以检查“nextAvailableTime”变量
  • 使用大调度。

标签: ios swift timer uibutton


【解决方案1】:

Timer 类有一个初始化器init(fire:interval:repeats:block),它允许您在它触发时设置Date。这将对您的问题有用。你必须小心一点,确保不要忘记安排计时器,否则它永远不会触发。

你可以用它来写一个这样的方法:

func disable(button buttonToDisable: UIButton, until date: Date) {
    buttonToDisable.isEnabled = false
    let timer  = Timer.init(fire: date, interval: 0, repeats: false) { _ in
        buttonToDisable.isEnabled = true
    }
    RunLoop.current.add(timer, forMode: .common)
}

此方法在给定日期之前禁用指定按钮。请注意,false 是为 repeats 参数传递的。我们只希望它运行一次。

使用此方法,您现在可以在按下按钮时执行以下操作:

let disabledTimeInterval = TimeInterval(30.0)
    
@IBAction func buttonPressed(_ sender: Any) {
    let disabledUntil = Date().advanced(by: disabledTimeInterval)
    disable(button: self.button, until: disabledUntil)
}

这负责在应用运行时启用和禁用按钮。但是您还提到您不希望用户能够停止和启动您的应用程序以避开超时。您可以通过将应禁用按钮的日期保存到UserDefaults 来处理此问题。以下代码显示了如何将Date 保存和加载到UserDefaults

    let buttonDisabledUntilDateKey = "buttonDisabledUntil"

    func save(disabledUntilDate date: Date) {
        UserDefaults.standard.set(date, forKey: buttonDisabledUntilDateKey)
    }
    
    func loadDisabledUntilDate() -> Date? {
        return UserDefaults.standard.object(forKey: buttonDisabledUntilDateKey) as? Date
    }

您现在可以修改buttonPressed 方法来保存此数据:

@IBAction func buttonPressed(_ sender: Any) {
    let disabledUntil = Date().advanced(by: disabledTimeInterval)
    save(disabledUntilDate: disabledUntil)
    disable(button: self.button, until: disabledUntil)
}

最后,当你的视图即将出现时,你应该检查当前时间是否早于按钮应该重新启用的时间,如果需要,禁用它。

override func viewWillAppear(_ animated: Bool) {
    let now = Date()
    if let buttonDisabledUntilDate = loadDisabledUntilDate(),
       now < buttonDisabledUntilDate {
        disable(button: self.button, until: buttonDisabledUntilDate)
    }
}

【讨论】:

  • 不幸的是,UserDefaults 的东西对我不起作用。我设法创建了一个按钮,一旦按下它,就会禁用一段时间,然后再次启用,直到再次按下它。但是每当我重新启动应用程序时,计时器都会重置。是否有另一种方法可以将计时器数据保存在 UserDefaults 中,以便在重新启动时不会重置?
  • 计时器无法在重新启动后继续存在。您必须重新创建它并使用保存的日期重置它。也许发布您正在使用的确切代码,有人将能够帮助您。关键部分是viewWillAppear 的东西你确定你正确地实现了吗?
  • 您共享的代码似乎没有使用我的答案中的任何代码。例如,您不使用init(fire:interval:repeats:block),您不会将任何内容保存到UserDefaults,也不会在应用重新启动时重新加载数据。尝试使用答案中的代码。
猜你喜欢
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多