因此,我有一个滑块和一个startTimer按钮,它根据滑块的值通过Timer.scheduledTimer间隔调用nextFood()函数。
[即使在按下startTimer按钮后,我仍想做的是,如果将滑块移动到其他值,则ScheduledTimer应该调整为新值,并根据新间隔调用nextFood函数,而无需尝试按再次单击startTimer按钮。
我的代码:
@IBOutlet var sliderVal: UISlider!
@IBAction func slider(_ sender: UISlider) {
delayLabel.text = "Delay: " + String(Int(sender.value)) + "s"
}
//start timer according to slider val
var timer = Timer()
@IBAction func startTimer(_ sender: UIButton) {
//print(Int(sliderVal.value))
startButton.isEnabled = false
timer = Timer.scheduledTimer(timeInterval: Double(Int(sliderVal.value)), target: self, selector: #selector(ViewController.nextFood), userInfo: nil, repeats: true)
}
到目前为止,我的代码仅适用于最初按下startTimer按钮时设置的滑块值,但是当我移动滑块时无法调整的值。非常感谢您的帮助!
您无需创建两个@IBAction
。您可以创建一个通用的@IBAction
,然后将按钮和滑块操作与此连接起来。
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var startButton: UIButton!
@IBOutlet weak var slider: UISlider!
var timer: Timer?
@IBAction func updateTimer(_ sender: Any) {
label.text = "Delay: " + String(Int(slider.value)) + "s"
startButton.isEnabled = false
timer?.invalidate()
timer = nil
timer = Timer.scheduledTimer(timeInterval: Double(Int(slider.value)), target: self, selector: #selector(ViewController.nextFood), userInfo: nil, repeats: true)
}
@objc func nextFood() {
///
}
}
注意:在初始化新的Timer
实例之前,请使之前的实例无效。其他多个计时器实例将调用nextFood
方法
您可以使用DispatchSourceTimer
来执行此操作,可以在不重新创建计时器实例的情况下重新启动它
var timer : DispatchSourceTimer?
@IBOutlet var sliderVal: UISlider!
@IBAction func slider(_ sender: UISlider) {
let delay = Int(sender.value)
delayLabel.text = "Delay: \(delay) s"
startTimer(with: delay)
}
//start timer according to slider val
@IBAction func startTimer(_ sender: UIButton) {
//print(Int(sliderVal.value))
startButton.isEnabled = false
startTimer(with: Int(sender.value))
}
func startTimer(with delay: Int)
let interval : DispatchTime = .now() + .seconds(delay)
if timer == nil {
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer!.schedule(deadline:interval, repeating: interval)
timer!.setEventHandler {
DispatchQueue.main.async {
self.nextFood()
}
}
timer!.resume()
} else {
timer!.schedule(deadline:interval, repeating: interval)
}
}