每个表格视图单元格一个计时器 [英] One timer per table view cell

查看:50
本文介绍了每个表格视图单元格一个计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想点击表格单元格并启动一个计时器。每个单元都应该有自己的计时器。我已经成功设置了计时器,但不是独立设置的,当我设置一个时,所有单元格都已设置。

I want to tap on table cell and start a timer. Every cell should have its own timer. I have managed to set the timer but not independently, when I set one all cells are set.

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()
}


推荐答案

这就是我要这样做的方法:

This is how I would do it:


  • 创建一个结构以表示包含以下内容的每一行开始时间以及该行当前是否正在运行

  • 安排一个重复计时器0.5秒以解决 Timer 中的抖动li>
  • 每次计时器触发时,更新具有运行中计时器的可见行

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()
        }
    }
}

这篇关于每个表格视图单元格一个计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆