Search code examples
iosswifteventsdelaycancellation

How Do I Cancel and Restart a Timed Event in Swift?


I have a sliderValueChange function which updates a UILabel's text. I want for it to have a time limit until it clears the label's text, but I also want this "timed clear" action to be cancelled & restarted or delayed whenever the UISlider is moved within the time limit before the "timed clear" action takes place.

So far this is what I have:

let task = DispatchWorkItem {
  consoleLabel.text = ""
}
func volumeSliderValueChange(sender: UISlider) {

  task.cancel()

  let senderValue = String(format: "%.2f", sender.value)
  consoleLabel.text = "Volume: \(senderValue)"

  DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3, execute: task)  
}

Obviously, this approach does not work, since cancel() apparently cannot be reversed.. (or at least I don't know how). I also don't know how to start a new task at the end of this function which will be cancelled if the function is recalled..

Am I going about this the wrong way? Is there something I am overlooking to make this work?


Solution

  • Use a timer:

    weak var clearTimer: Timer?
    

    And:

    override func viewDidLoad() {
      super.viewDidLoad()
      startClearTimer()
    }
    
    func startClearTimer() {
      clearTimer = Timer.scheduledTimer(
        timeInterval: 3.0,
        target: self,
        selector: #selector(clearLabel(_:)),
        userInfo: nil,
        repeats: false)
    }   
    
    func clearLabel(_ timer: Timer) {
       label.text = ""
    }
    
    func volumeSliderValueChange(sender: UISlider) {
       clearTimer?.invalidate()  //Kill the timer
       //do whatever you need to do with the slider value
       startClearTimer()  //Start a new timer
    }