我的目标是有一个独特的 (hh:mm:ss) 倒计时 timer
对于每个填充的 uicollectionviewcell
在 uicollectionview
内.
下面是我能够编译的(缩写的)代码,但我坚持让它以任何身份真正工作......任何指导将不胜感激。
class VC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var timer = Timer()
var secondsRemaining: Int?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! ExampleCollectionViewCell
let expirationDate = Calendar.current.date(byAdding: .hour, value: 24, to: startDate)
secondsRemaining = expirationDate?.seconds(from: startDate)
timer = Timer(timeInterval: 1, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)
return cell
}
@objc func countdown() {
secondsRemaining = secondsRemaining! - 1
if secondsRemaining == 0 {
print("CELL TIME HAS EXPIRED!")
timer.invalidate()
} else {
let hours = secondsRemaining! / 3600
let minutes = (secondsRemaining! % 3600) / 60
let seconds = (secondsRemaining! % 3600) % 60
let countdownLabelString = String(format: "%02d:%02d:%02d", hours, minutes, seconds)
//i need to take this countdownLabelString and set it to the
//countdownLabel.text that is an element of each cell. i tried
//doing all of this in the cell subclass, but no luck...
}
}
}
最佳答案
Collection View 单元格不会不断更新。如果你想让他们更新,你必须告诉他们更新。
如果您希望每个单元格显示不同的剩余时间,您需要一个数据模型,为您显示的每个 indexPath 保存一个单独的 expirationDate
。如果您的 Collection View 是一个简单的一维项目列表,例如 TableView ,那么您可以只使用一维数组。如果您的 Collection View 显示单元格网格,您可能需要一个二维模型对象数组。
每次将项目添加到数据模型时,都包含一个 expirationDate
值。 (该项目过期的日期
。)
然后让您的计时器在每次触发时调用 Collection View 的 reloadData
方法。
在您的 collectionView(collectionView:cellForItemAt:)
方法中,使用 indexPath 确定要显示的数据模型中的项目。查找该 indexPath 的 expirationDate
,计算从现在到到期日期的剩余时间,并在单元格中显示该信息。 (使用 Calendar
方法 dateComponents(_:from:to:)
计算从现在到到期日期之间的小时数、分钟数和秒数。)
编辑
不要每次计时器触发时都递减计数器。使用 dateComponents(_:from:to:)
编辑#2:
下面是一个示例 Collection View Controller ,它可以执行您想要的操作:
import UIKit
private let reuseIdentifier = "aCell"
class DatesCollectionVC: UICollectionViewController {
weak var timer: Timer?
var dates: [Date] = []
lazy var componentsFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
return formatter
}()
override func viewDidLoad() {
super.viewDidLoad()
for _ in 1...100 {
let interval = Double(arc4random_uniform( 10000)) + 120
dates.append(Date().addingTimeInterval(interval))
}
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
self.collectionView?.reloadData()
}
}
// MARK: - UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dates.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? MyCell else {
return UICollectionViewCell()
}
let now = Date()
let expireDate = dates[indexPath.row]
guard expireDate > now else {
cell.intervalLabel.text = "00"
return cell
}
let desiredComponents: Set<Calendar.Component> = [.hour, .minute, .second]
let components = Calendar.current.dateComponents(desiredComponents, from: now, to: expireDate)
cell.intervalLabel.text = self.componentsFormatter.string(from: components)
return cell
}
}
上面的代码是这样的:
关于ios - 向 UICollectionView 添加多个倒数计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50011472/