当我滚动tableView单元格时,此单元格中的运行计时器将重置并停止运行

时间:2018-06-08 13:26:20

标签: ios swift uitableview timer countdown

每个单元格中都有一个计时器和开始按钮,当我单击该单元格中的开始按钮时,timeLabel将开始显示倒计时。

现在一切正常但我发现当我将正在运行的计时器滚出屏幕并向后滚动时,计时器将重置并停止。

cellForRow:

async function runner(fn, params?): Promise<any> {
  return new Promise(function(resolve, reject) {
    const _CB = cb.bind({ resolve, reject });
    if (params) {
      return fn(params, _CB);
    }

    return fn(_CB);
  });
}

const one = async (): Promise<any> => {
  return runner((x) => sdk.one(x));
};

当我滚动tableView时,我希望计时器仍在运行。

2 个答案:

答案 0 :(得分:0)

嗨,当你出列ReusableCell时,将重复使用该单元格,这将使得单元格得到刷新,因为如果你可以删除 dequeueReusableCell 你更少的单元格,你将从开始再次获得计时器可以保留一个数组来存储每个单元的计时器数。

在单元格声明并在每个单元格中更新数组时分配数组val  计时器增量。

答案 1 :(得分:0)

这是一个可能有用的答案。

UITableViewCells仅在屏幕上存在。所以你所经历的是预期的行为。 基本上你需要定时器存在于UITableViewCell范围之外,否则当它们离开屏幕时它们将被销毁。所以这就是你如何做到这一点:

创建一个UITableVIew的子类(您应该使用此类而不是您当前使用的TableViewController,或者只是将稍后添加的代码添加到当前的TableViewController类中):

class HeXiaoManTableViewController:  UITableViewController {

}

在此子类中,创建一个数组(或您选择的数据结构)来存储计时器。我假设您正在使用NSTimer,但这适用于您拥有的任何计时器类。

class HeXiaoManTableViewController:  UITableViewController {

    public var timerArray: [NSTimer] = []
}

现在,在创建单元格时,请向阵列添加新计时器。对于数组,我根据它的索引在数组中存储UITableViewCell。所以第一个UITableViewCell(索引0)将进入数组的索引0 ...但是说用户向上和向下滚动,多次显示第一个单元格。我假设您希望该计时器仅启动一次。所以你需要检查计时器是否已经存在。如果确实如此,那就别管它了。否则添加计时器。您可以根据需要自定义此功能:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var timer = NSTimer()
    timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
    if (timerArray.indices.contains(index)) {
        timerArray.insert(timer, at: index)
    }
}

您应该可以在以后访问此数组以获取单个计时器。希望这有帮助!

修改:在课程中进行更改

<强> TimerTableViewCell.swift

import UIKit

class TimerTableViewCell: UITableViewCell {

public var timeInLabel: Int = -1
public var viewController: ViewController?
var index: Int = -1
var timer:Timer?

var tableView: UITableView? {
    var view = self.superview
    while (view != nil && view!.isKind(of: UITableView.self) == false) {
        view = view!.superview
    }
    return view as? UITableView
}

@IBOutlet weak var timerName: UILabel!
@IBOutlet weak var secondLeftLabel: UILabel!
@IBAction func stopButton(_ sender: UIButton) {

    timer?.invalidate()

}

@IBAction func playButton(_ sender: UIButton) {

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)
    RunLoop.current.add(self.timer!, forMode: RunLoopMode.commonModes)

}

@objc func updateTimer() {

    var timeInLabel = Int(secondLeftLabel.text!)!
    timeInLabel -= 1
    viewController?.timerArray[index] = timeInLabel
    secondLeftLabel.text = String(timeInLabel)

}

}

<强> ViewController.swift

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate {

public var timerArray: [Int] = []

var myTimerList = CustomTimerList()

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
    for timer in CustomTimerList.timerList {
        timerArray.append(timer.timerSecond)
    }
    super.viewDidLoad()
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return CustomTimerList.timerList.count
}

var selectedIndexArray:[Int] = []

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! TimerTableViewCell
    cell.timer?.invalidate()
    let item = CustomTimerList.timerList[indexPath.row]
    cell.timerName.text = item.timerName
    cell.secondLeftLabel.text = "\(timerArray[indexPath.row])"
    cell.index = indexPath.row
    cell.viewController = self

    return cell


}

}