xcode ios - обновление запланированного таймера при настройке слайдера - PullRequest
0 голосов
/ 04 февраля 2020

Итак, у меня есть ползунок и кнопка startTimer, которая вызывает функцию nextFood() через интервал Timer.scheduledTimer в зависимости от значения ползунка.

Что я пытаюсь сделать, даже после того, как я нажал кнопку startTimer, если я переместил ползунок на другое значение, scheduleTimer должен настроить новое значение и вызвать функцию 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, но не корректируется при перемещении ползунка. Любая помощь очень ценится!

Ответы [ 3 ]

0 голосов
/ 04 февраля 2020

Вам не нужно создавать два @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 голосов
/ 04 февраля 2020

Вы можете сделать это с помощью 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(sliderVal!.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: TimeInterval(delay))
        timer!.setEventHandler {
            DispatchQueue.main.async {
                self.nextFood()
            }
        }
        timer!.resume()
    } else {
        timer!.schedule(deadline:interval, repeating: TimeInterval(delay))
    }
}
0 голосов
/ 04 февраля 2020

Краткий ответ: Вы не можете изменить временной интервал таймера после его запуска.

То, что вы можете сделать, это: После действия ползунка аннулируйте предыдущий таймер, создайте новый таймер и запустите его с новым интервалом.

Это также связано с вашей проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...