简体   繁体   English

当 collectionview 刷新时,CollectionView 单元格的计时器会混淆

[英]CollectionView cell's timers get mixed up when collectionview refreshes

I have a collectionView that contains timers in each cell.我有一个 collectionView,它在每个单元格中包含计时器。 When the app starts all the timers work fine, however, when I refresh the collection view all the timers get mixed up and are all over the place.当应用程序启动时,所有计时器都可以正常工作,但是,当我刷新集合视图时,所有计时器都会混淆并且到处都是。 I am pretty sure it has something to do with the previous timers not closing.我很确定这与之前的计时器没有关闭有关。

Code for collection view:集合视图的代码:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "contestsCell", for: indexPath) as! ContestsCollectionViewCell
    cell.nameLabel.text = listingArray[indexPath.row].name


    let arr = [listingArray[indexPath.row].expiryDate, cell.expiryDateLabel] as [AnyObject]

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCounting), userInfo: arr, repeats: true)

    return cell
}

Code for timer function:定时器功能代码:

@objc func updateCounting(timer:Timer){
    // here we set the current date

    var dateArray: [AnyObject] = timer.userInfo as! [AnyObject]

    let itemDate = dateArray[0] as! String
    var dateList = itemDate.components(separatedBy: "-")

    let dateLabel = dateArray[1] as! UILabel

    let date = NSDate()
    let calendar = Calendar.current

    let components = calendar.dateComponents([.hour, .minute, .month, .year, .day, .second], from: date as Date)

    let currentDate = calendar.date(from: components)

    let userCalendar = Calendar.current

    // here we set the due date. When the timer is supposed to finish
    let competitionDate = NSDateComponents()
    competitionDate.year = Int(dateList[0])!
    competitionDate.month = Int(dateList[1])!
    competitionDate.day = Int(dateList[2])!
    competitionDate.hour = 00
    competitionDate.minute = 00
    competitionDate.second = 00
    let competitionDay = userCalendar.date(from: competitionDate as DateComponents)!

    //here we change the seconds to hours,minutes and days
    let CompetitionDayDifference = calendar.dateComponents([.day, .hour, .minute, .second], from: currentDate!, to: competitionDay)


    //finally, here we set the variable to our remaining time
    let daysLeft = CompetitionDayDifference.day
    let hoursLeft = CompetitionDayDifference.hour
    let minutesLeft = CompetitionDayDifference.minute
    let secondsLeft = CompetitionDayDifference.second

    if competitionDay > currentDate as! Date {
        //Set countdown label text
        dateLabel.text = "\(daysLeft ?? 0): \(hoursLeft ?? 0): \(minutesLeft ?? 0): \(secondsLeft ?? 0)"
    }

}

code for refreshing collectionView刷新collectionView的代码

@objc func loadData() {

    retrieveContests()
    listingArray.removeAll()
    self.refresher.endRefreshing()
}

I think your problem has to do with the fact that you dequeue your cells.我认为您的问题与您的单元格出列有关。 Since the principle behind this is that existing cell objects are being reused by iOS that might lead to some problems.因为这背后的原理是现有的单元格对象正在被 iOS 重用,这可能会导致一些问题。

Eg in the method you create cell1 with countdown1 and a timer and the same with cell2 and countdown2 (+timer).例如,在您创建带有 countdown1 和计时器的 cell1 的方法中,使用 cell2 和 countdown2 (+timer) 也是如此。 Once you reload your collectionView cell1 and cell2 will be reused, but now cell1 will have a different index path and is therefor used for countdown2 and also a new timer is created as well.一旦你重新加载你的 collectionView cell1 和 cell2 将被重用,但现在 cell1 将有一个不同的索引路径,因此用于 countdown2 并且还创建了一个新的计时器。

This probably leads to the problem that your timers are getting mixed up in the process and as far as I can see in your code you are also never stopping any timers, so your assumption is correct I would say.这可能会导致您的计时器在此过程中混淆的问题,据我在您的代码中看到的,您也从未停止任何计时器,因此我会说您的假设是正确的。 Every time you reload your collection view, your are creating more timers.每次重新加载集合视图时,都会创建更多计时器。

My suggestion to solve this would be: Create a property on each cell that contains the Date-object which you use to calculate the countdown.我解决这个问题的建议是:在每个包含用于计算倒计时的日期对象的单元格上创建一个属性。 Then just use a single timer which notifies all cells to update their content on their own.然后只需使用一个计时器通知所有单元格自行更新其内容。 Maybe you could use NotificationCenter for this.也许您可以为此使用 NotificationCenter。 This (or a similar approach) should help you and avoid the whole problem with maintaining all these timers.这(或类似的方法)应该可以帮助您并避免维护所有这些计时器的整个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从collectionView中显示时获取单元格的indexPath - Get indexPath of cell when it's being shown from collectionView 当不是可见单元格时获取单元格集合的值 - Get values of cell collectionView when not are visible cells 滚动时单元格元素放错位置-CollectionView - Cell elements get misplaced when scrolling - CollectionView 当点击collectionView单元格内的按钮时,如何获取表格视图行并从位于tableViewCell内的collectionView推送到viewController - how to get table view row and push to viewController from collectionView that's inside a tableViewCell when tapped button inside collectionView cell 如何让 imageView 占据 CollectionView Cell? - How do I get an imageView to take up a CollectionView Cell? Swift - 在collectionView首次加载时如何自动选择单元格? - Swift - how automatically select cell when collectionView first loads up? Swift CollectionView获取第一个单元格 - Swift CollectionView get first cell 滑动时已选择CollectionView单元格 - CollectionView cell is selected when swiped on 选定时CollectionView单元移动 - CollectionView Cell Moving when Selected 是否有可能在collectionview sizeForItemAtIndexPath委托方法内获取单元格的标记? - Is it possible to get a cell's tag within the collectionview sizeForItemAtIndexPath delegate method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM