I am working on my UITableviewcell where I have a UIView for user to "tap" and start timer. I am creating my UItableview cell components completely programmatically and adding timer components within UITableviewcell class instead of the parent view controller.
The problem I am having is that my timer is supposed to be distinct for each UITableviewcell. User should be able to start timer in one cell and scroll through other cells to start/stop another. However, when I "tap" on my first cell, the timer gets started not only on the first one, but I can also see that it is starting on the 3rd cell.
I tried to rectify this issue by using PrepareForReuse and invalidate timer, but it also result in the 1st cell's timer to be invalidated.
I tried to research on this issue, but have found no exact match. Could anyone kindly advise how I can resolve this issue?
class ActiveExerciseTableViewCell: UITableViewCell, UITextFieldDelegate {
static let tableviewidentifier = "activeExerciseTableViewCell"
var tableviewContentViewTabBarHeight = CGFloat()
var exerciseCellKeyboardHeight = CGFloat()
var restTimer = Timer()
var restTimeRemaining: Int = 180
var isRestTimerRunning: Bool = false
let activeExerciseTimerUIView: UIView = {
let activeExerciseTimerUIView = UIView()
activeExerciseTimerUIView.backgroundColor = .darkGray
return activeExerciseTimerUIView
}()
let timerLabel: UILabel = {
let timerLabel = UILabel()
timerLabel.text = "180"
timerLabel.textColor = .black
timerLabel.adjustsFontSizeToFitWidth = true
return timerLabel
}()
override func prepareForReuse() {
super.prepareForReuse()
if self.isRestTimerRunning == false {
restTimer.invalidate()
restTimeRemaining = 180
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
}
func setUpActiveExerciseUIViewLayout(){
timerLabel.translatesAutoresizingMaskIntoConstraints = false
timerLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
timerLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.55).isActive = true
timerLabel.widthAnchor.constraint(equalToConstant: contentView.frame.width * 0.7).isActive = true
timerLabel.heightAnchor.constraint(equalToConstant: 80).isActive = true
timerLabel.font = .boldSystemFont(ofSize: 64)
activeExerciseTimerUIView.translatesAutoresizingMaskIntoConstraints = false
activeExerciseTimerUIView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
activeExerciseTimerUIView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.25).isActive = true
activeExerciseTimerUIView.widthAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.heightAnchor.constraint(equalToConstant: 225).isActive = true
let timerStartGesture = UITapGestureRecognizer(target: self, action: #selector(playTapped))
timerStartGesture.numberOfTapsRequired = 1
activeExerciseTimerUIView.addGestureRecognizer(timerStartGesture)
activeExerciseTimerUIView.isUserInteractionEnabled = true
}
@objc func playTapped(_ sender: Any) {
if isRestTimerRunning == false {
restTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(step), userInfo: nil, repeats: true)
self.isRestTimerRunning = true
}
}
@IBAction func pauseTapped(_ sender: Any) {
restTimer.invalidate()
}
@IBAction func resetTapped(_ sender: Any) {
restTimer.invalidate()
restTimeRemaining = 180
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
@objc func step() {
if restTimeRemaining > 0 {
restTimeRemaining -= 1
} else {
restTimer.invalidate()
restTimeRemaining = 180
}
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
public func prodTimeString(time: TimeInterval) -> String {
let Minutes = Int(time) / 60 % 60
let Seconds = Int(time) % 60
return String(format: "%02d:%02d", Minutes, Seconds)
}
Iam posting my own answer, issue had been resolved the issue by
UItableView Delegate