uitableviewcell example custom ios swift uitableview cocoa-touch

ios - example - uitableview swift 4



Un temporizador por celda de vista de tabla (1)

Así es como lo haría:

  • Cree una estructura para representar cada fila que contenga una hora de inicio y si esa fila se está ejecutando actualmente
  • Programe un temporizador repetitivo durante 0.5 segundos para tener en cuenta la fluctuación en Timer
  • Cada vez que se active el temporizador, actualice las filas visibles que tienen temporizadores "en ejecución"

import UIKit struct TimerModel { private var startTime: Date? private var offset: TimeInterval = 0 var elapsed : TimeInterval { get { return self.elapsed(since:Date()) } } var isRunning = false { didSet { if isRunning { self.startTime = Date() } else { if self.startTime != nil{ self.offset = self.elapsed self.startTime = nil } } } } func elapsed(since: Date) -> TimeInterval { var elapsed = offset if let startTime = self.startTime { elapsed += -startTime.timeIntervalSince(since) } return elapsed } } class ViewController: UIViewController { @IBOutlet weak var tableview: UITableView! var timer: Timer? var timersActive = 0 let formatter: DateComponentsFormatter = { let formatter = DateComponentsFormatter() formatter.zeroFormattingBehavior = .pad formatter.allowedUnits = [.hour, .minute, .second] return formatter }() var timers = [TimerModel](repeating:TimerModel(), count:30) override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func elapsedTimeSince(_ startTime: Date) -> String { let elapsed = -startTime.timeIntervalSinceNow return self.formatter.string(from: elapsed) ?? "0:00:00" } func startTimer() { self.timersActive += 1 guard self.timer == nil else { return } self.timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: { [weak self] (timer) in if let me = self { for indexPath in me.tableview.indexPathsForVisibleRows ?? [] { let timer = me.timers[indexPath.row] if timer.isRunning { if let cell = me.tableview.cellForRow(at: indexPath) { cell.textLabel?.text = me.formatter.string(from: timer.elapsed) ?? "0:00:00" } } } } }) } func stopTimer() { self.timersActive -= 1 if self.timersActive == 0 { self.timer?.invalidate() self.timer = nil } } } extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.timers.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) let timer = self.timers[indexPath.row] cell.imageView?.image = timer.isRunning ? #imageLiteral(resourceName: "GreenDot") : #imageLiteral(resourceName: "RedDot") cell.textLabel?.text = self.formatter.string(from: timer.elapsed) ?? "0:00:00" return cell } } extension ViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { self.timers[indexPath.row].isRunning = !self.timers[indexPath.row].isRunning self.tableview.reloadRows(at: [indexPath], with: .none) if self.timers[indexPath.row].isRunning { self.startTimer() } else { self.stopTimer() } } }

Quiero tocar en la celda de la mesa e iniciar un temporizador. Cada celda debe tener su propio temporizador. He logrado configurar el temporizador, pero no de forma independiente, cuando configuro uno, todas las celdas están configuradas.

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let currentCell = tableView.cellForRow(at: indexPath) as! StaffTableViewCell if isRunning == false { currentCell.cellImageView.image = UIImage(data: UIImagePNGRepresentation(#imageLiteral(resourceName: "greendot"))!) timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in counter += 1 let hourPortion = String(format: "%02d", counter / 3600) let minutesPortion = String(format: "%02d", counter / 60) let secondsPortion = String(format: "%02d", counter % 60) //print("/(hourPortion):/(minutesPortion):/(secondsPortion)") timeTotal = "/(hourPortion):/(minutesPortion):/(secondsPortion)" currentCell.timerLabel.text = timeTotal isRunning = true } } tableView.reloadData() } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { timer.invalidate() isRunning = false let currentCell = tableView.cellForRow(at: indexPath) as! StaffTableViewCell if let data = UIImagePNGRepresentation(#imageLiteral(resourceName: "reddot")) { currentCell.cellImageView.image = UIImage(data: data) } tableView.reloadData() }