我有一个collectionView,每个单元格中都包含计时器。当应用程序启动时,所有计时器都可以正常工作,但是,当我刷新集合视图时,所有计时器都会混合在一起,并且到处都是。我很确定这与以前的计时器没有关闭有关。
集合视图的代码:
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
}
计时器功能代码:
@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)"
}
}
用于刷新collectionView的代码
@objc func loadData() {
retrieveContests()
listingArray.removeAll()
self.refresher.endRefreshing()
}
答案 0 :(得分:0)
我认为您的问题与您出队的事实有关。由于其背后的原理是iOS会重用现有的单元对象,这可能会导致一些问题。
例如在该方法中,您使用countdown1和一个计时器创建cell1,并使用cell2和countdown2(+ timer)创建一个。重新加载collectionView后,cell1和cell2将被重用,但是现在cell1将具有不同的索引路径,并因此用于countdown2,并且还创建了一个新计时器。
这可能会导致问题,您的计时器在过程中变得混乱,据我在您的代码中看到的那样,您也永远不会停止任何计时器,因此您的假设是正确的。每次重新加载集合视图时,您都会创建更多计时器。
我建议的解决方法是:在每个包含用于计算倒数的日期对象的单元格上创建一个属性。然后,只需使用一个计时器即可通知所有单元自行更新其内容。也许您可以为此使用NotificationCenter。 这种(或类似的方法)应该可以为您提供帮助,并避免维护所有这些计时器的整个问题。