我正在创建一个包含列表的应用程序,该列表将在一定时间内有效。为此,我在每个单元格上创建一个倒计时条动画。每个单元格都有其自己的自定义持续时间,此后单元格将显示“时间到”。该单元甚至在滴答到0时显示时间(以秒为单位),然后显示“ Time's Up”消息。
在此上方,有一个倒计时栏动画。我正在控制来自viewController的所有这些动画,而不是在customView单元中执行这些动画,因为单元的可重用性使计时器陷入困境。
我正在使用两个计时器:
Timer()
:每1秒调用一次。这用于简单的秒倒计时。我正在使用包含两个变量durationTime
和width
的struct类型数组。 width
默认设置为400。 durationTime
由用户设置。
@objc func handleCountdown() {
let arrayLength = duration.count
var i: Int = 0
var timeCount: Int = 0
for _ in 0..<arrayLength {
let value = duration[i].durationTime - 1 //Decreasing the timer every second
let indexPath = IndexPath(row: i, section: 0)
if (value > 0)
{
duration[i].durationTime = value
if let cell = listTableView.cellForRow(at: indexPath) as! listTableViewCell? {
cell.testlabel.text = "\(value)"
}
//listTableView.reloadRows(at: [indexPath], with: .automatic)
i = i + 1
} else {
if let cell = listTableView.cellForRow(at: indexPath) as! listTableViewCell? {
cell.testlabel.text = "Time's Up"
}
i = i + 1
timeCount = timeCount + 1
}
}
if (timeCount == (arrayLength - 1)) {
self.timer?.invalidate()
}
}
上面的代码每秒被调用一次。它递减时间的值,然后将其显示在表格视图单元格中。上面的代码可以正常工作。
CADisplayLink
:此计时器用于运行进度条动画。但是,在这种情况下,我要计算经过的时间,然后将其除以每个元素的durationTime并计算百分比。该百分比用于更新每个进度条的width
的值。 (请记住,durationBar只是duration数组的重复项。但是,在该数组中,durationTime不会递减->仅用于测试目的)这是代码:
@objc func handleProgressAnimation() {
let currenttime = Date()
let elapsed = currenttime.timeIntervalSince(animationStartDate)
let totalWidth: Double = 400.0
print(elapsed)
let arrayLength = duration.count
var i: Int = 0
for _ in 0..<arrayLength {
let indexPath = IndexPath(row: i, section: 0)
let percentage = (elapsed / Double(durationBar[i].durationTime))
let newWidth = Double(totalWidth - (totalWidth * percentage))
durationBar[i].width = newWidth
if let cell = listTableView.cellForRow(at: indexPath) as! listTableViewCell? {
cell.timeRemainingView.frame.size.width = CGFloat(durationBar[indexPath.row].width)
}
i = i + 1
}
}
问题:一段时间后,即使时间尚未完成,某些进度条也会从单元格中消失。一旦在tableview上进行了一些滚动,它就会经常发生。
这是willDisplayCell
和cellForRowIndexPath
:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellid, for: indexPath) as! listTableViewCell
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell:listTableViewCell = cell as! listTableViewCell
cell.testlabel.text = "\(duration[indexPath.row].durationTime)"
cell.timeRemainingView.frame.size.width = CGFloat(duration[indexPath.row].width)
}
如下面的图片所示,经过一段时间后,即使还有一些时间,进度条也消失了:
这里的问题是什么,我正在控制viewController而不是单元中的所有动画和计时器,以防止单元可重用性成为问题。需要帮助!
答案 0 :(得分:0)
问题是您用{p>更新cell.timeRemainingView.frame.size.width
durationBar[indexPath.row].width
代表handleProgressAnimation
和
duration[indexPath.row].width
代表willDisplayCell
。
我也将切换到tableView.indexPathsForVisibleRows以仅针对可见单元格更新UI,这样它就不会为if-let中的每个单元格调用.cellForRow。