将多个倒计时器添加到UICollectionView

时间:2018-04-24 22:17:59

标签: ios swift timer uicollectionview uicollectionviewcell

我的目标是为timer中每个已填充的uicollectionviewcell设置一个唯一的(hh:mm:ss)倒计时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... 
    }
} 
}

1 个答案:

答案 0 :(得分:1)

不会不断更新集合视图单元格。如果您希望它们更新,您必须告诉他们更新。

如果希望每个单元格显示不同的剩余时间,则需要一个数据模型,为您显示的每个indexPath保存单独的expirationDate。如果您的集合视图是一个简单的一维项目列表,如表格视图,那么您可以使用一维数组。如果您的集合视图显示单元格网格,则可能需要二维模型对象数组。

每次向数据模型添加项目时,都要包含expirationDate值。 (当该项目到期时Date。)

然后让你的计时器每次触发时调用集合视图的reloadData方法。

collectionView(collectionView:cellForItemAt:)方法中,使用indexPath确定要显示的数据模型中的哪个项目。查找该indexPath的expirationDate,计算从现在到到期日期的剩余时间,并在单元格中显示该信息。 (使用Calendar方法dateComponents(_:from:to:)计算从现在到您的到期日期之间的小时数,分钟数和秒数。)

修改

每次计时器触发时,

不要递减计数器。使用dateComponents(_:from:to:)

对过期日期与当前日期之间的差异进行数学计算

编辑#2:

示例集合视图控制器可以执行以下操作:

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

上面的代码如下所示:

enter image description here