Reputation: 1723
In order to have a consistent implementation of a count down timer (counting down the recording time of audio) in each of my tableView cells, I placed a timer in a custom cell called 'createStoryCell' which is fired when 'countDownTime' is set.
class CreateStoryCell: UITableViewCell {
weak var delegate: createStoryCellDelegate?
var countDownTimer : Timer?
var countDownTime : Double! {
didSet {
startTimer()
}
}
func startTimer() {
countDownTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (countDownTimer) in
if self.countDownTime > 0.0 {
self.countDown.isHidden = false
self.countDownTime = self.countDownTime - 1.0
self.countDown.text = String(self.countDownTime)
} else {
countDownTimer.invalidate()
}
}
}
}
To set the countDownTime I use the following code in the 'cellForRowAt' in my viewController.
if storyItem?.isRecording == false {
cell.record.setImage(UIImage(named: "smallMicBtn"), for: .normal)
cell.countDown.isHidden = true
} else {
cell.countDownTime = 5.0
cell.record.setImage(UIImage(named: "recordStop"), for: .normal)
}
However, when I run the count down timer it skips numbers outputting only 4...2...0. I'd be grateful for any suggestions on how to avoid the skipping of 3 and 1. I have already tried to wrap the 'self.countDown.text = String(self.countDownTime)' in dispatchQueue.main.async but with the same result. Thanks in advance for any pointers.
Upvotes: 0
Views: 83
Reputation: 100503
This
didSet {
startTimer()
}
triggers every change of countDownTime
here
self.countDownTime = self.countDownTime - 1.0
You shouldn't use didSet
, make it a method and call it once from CellForRowAt
Note also cells are dequeeud so after this line inside CellForRowAt
do
let cell = ///
cell.countDownTimer?.invalidate()
in case user scrolls
Upvotes: 4