Таймеры ячейки CollectionView запутываются при обновлении collectionView - PullRequest
0 голосов
/ 02 января 2019

У меня есть 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()
}

1 Ответ

0 голосов
/ 02 января 2019

Я думаю, что ваша проблема связана с тем фактом, что вы отказываетесь от своих клеток.Поскольку принцип заключается в том, что существующие объекты ячеек повторно используются iOS, что может привести к некоторым проблемам.

Например, в методе, который вы создаете, cell1 с обратным отсчетом1 и таймером и то же самое с cell2 и countdown2 (+ timer).Как только вы перезагрузите ваш collectionView, cell1 и cell2 будут использоваться повторно, но теперь cell1 будет иметь другой путь индекса и поэтому будет использоваться для countdown2, а также будет создан новый таймер.

Это, вероятно, приводит к проблеме, заключающейся в том, что ваши таймеры смешиваются в процессе, и, насколько я вижу в вашем коде, вы также никогда не останавливаете какие-либо таймеры, поэтому я бы сказал, что ваше предположение верно.Каждый раз, когда вы перезагружаете представление вашей коллекции, вы создаете больше таймеров.

Я предлагаю решить эту проблему: Создайте свойство в каждой ячейке, которое содержит объект Date, который вы используете для вычисления обратного отсчета.Затем просто используйте один таймер, который уведомляет все ячейки, чтобы они самостоятельно обновляли свой контент.Может быть, вы могли бы использовать NotificationCenter для этого.Этот (или аналогичный подход) должен помочь вам и избежать всей проблемы с поддержанием всех этих таймеров.

...