xcode ios-调整滑块时更新计划的计时器

问题描述 投票:0回答:3

因此,我有一个滑块和一个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按钮时设置的滑块值,但是当我移动滑块时无法调整的值。非常感谢您的帮助!

ios swift xcode
3个回答
0
投票

简短的回答:计时器启动后就无法更改其时间间隔。

您可以做的是:在执行滑块操作时,使先前的计时器无效,创建一个新的计时器,并以新的间隔触发它。

[This也与您的问题有关。


0
投票

您无需创建两个@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方法


0
投票

您可以使用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)
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.