Reputation:
↑↑↑↑↑↑↑↑↑ I show the problem in this GIF ↑↑↑↑↑
There is a timer and stratButton in the tableView cell, when I click the Button, the timeLabel will start running.
Now the problem is when I scroll the running timer out of the screen and scroll it back, the timer will reset and stop.
Hope someone can help me! I check many solution but they didn't work for me! I am almost cry.
my cellForRow:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! TimerTableViewCell
cell.timer?.invalidate()
let item = myTimerList[indexPath.row]
cell.timerName.text = item.timerName
cell.secondLeftLabel.text = "\(item.timerSecond)"
return cell
}
I created a small project contained my code for you to modify : https://app.box.com/s/axluqkjg0f7zjyigdmx1lau0c9m3ka47
Upvotes: 1
Views: 648
Reputation: 100503
You need to preserve the state of each cell
class Service {
static let shared = Service()
var myTimerList = [TimerClass]()
}
//
here i added another 2 vars , why timerName
is left despite you have to init them the same because current
will hold the changing value
class TimerClass {
let timerSecond : Int
let timerName : String
var current: Int
var isPlaying = false
init(second:Int, name:String) {
timerSecond = second
timerName = name
current = second
}
}
//
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! TimerTableViewCell
let item = Service.shared.myTimerList[indexPath.row]
cell.tag = indexPath.row // to access the array inside the cell
if item.isPlaying {
cell.play() // add play method to the cell it has same button play action
}
else {
cell.timer?.invalidate()
}
cell.timerName.text = item.timerName
cell.secondLeftLabel.text = "\(item.current)"
return cell
}
//
inside the cell when the button is clicked , change isPlaying property to true and to false when stopped like this
// here self is the cell itself
Service.shared.myTimerList[self.tag].isPlaying = true
also when the timer ticks change
Service.shared.myTimerList[self.tag].current = // value
Upvotes: 1
Reputation: 56
Remove cell.timer?.invalidate()
from cellForRowAt
method, because every time you scroll the tableView
this method is called to display new cells. In your case when you have started a timer for a cell and that cell is not in the view, next time you scroll to bring that cell again to the view cell.timer?.invalidate()
causes it to stop.
Upvotes: 0
Reputation: 4884
You are reusing UITableViewCell
. It means once cell is out of screen, it will be reused for the cell getting into the screen. Whenever it happens, it calls the delegate method - means cell.timer?.invalidate()
is invoked again and again.
Upvotes: 0