SubViews дублируются в ячейках collectionView?
У меня есть collectionView, который представляет промежуток времени. Каждая клетка - это месяц. В каждой ячейке есть горизонтальное представление стека, где каждое представление представляет день.
Полный проект находится здесь, если вы хотите попробовать его: https://github.com/AlexMarshall12/iOS-timeline
В моем ViewController я генерирую случайный массив дат. Каждый раз, когда ячейка вызывается в cellForItemAt, пользовательская функция находит даты в массиве, которые находятся в месяце ячейки.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MonthCollectionViewCell", for: indexPath) as! MonthCollectionViewCell
cell.backgroundColor = UIColor.gray
let firstDate = dates.first
let index = indexPath.item
let monthDate = Calendar.current.date(byAdding: .month, value: index, to: firstDate as! Date)
let monthInt = Calendar.current.component(.month, from: monthDate!)
let yearInt = Calendar.current.component(.year, from: monthDate!)
cell.monthLabel.text = String(monthInt)+" "+String(yearInt)
cell.year = yearInt
cell.month = monthInt
let monthDates = dates(self.dates as! [Date], withinMonth: monthInt, withinYear: yearInt)
cell.colorViews(monthDates:monthDates)
return cell
}
func dates(_ dates: [Date], withinMonth month: Int, withinYear year: Int) -> [Date] {
let calendar = Calendar.current
let components: Set<Calendar.Component> = [.month,.year]
let filtered = dates.filter { (date) -> Bool in
let monthAndYear = calendar.dateComponents(components, from: date)
return (monthAndYear.month == month && monthAndYear.year == year)
}
return filtered
}
Они передаются в пользовательский класс ячеек, и он находит подпредставления, которые представляют эти дни, и окрашивает их так:
class MonthCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var monthLabel: UILabel!
@IBOutlet weak var stackView: UIStackView!
var year: Int?
var month: Int?
override func awakeFromNib() {
super.awakeFromNib()
for _ in 0...30 { //for the 31 days in a month...
let tick = UIView()
self.stackView?.addArrangedSubview(tick)
}
}
func colorViews(monthDates: [Date]){
for date in monthDates {
let dayIndex = Calendar.current.component(.day, from: date)
let tick = stackView.arrangedSubviews[dayIndex]
tick.backgroundColor = UIColor.red
}
}
}
Я считаю, что это должно дать мне желаемый эффект. Например, если есть 3 даты, сгенерированные за 2 года, это создаст 3 полоски за 2 года ячеек месяца. Тем не менее, я обнаружил, что визуализируется более 3 полос, почти как если бы они дублировали подпредставление во многих ячейках.
Вот как это выглядит сейчас: https://imgur.com/a/ZNSmIS8. Обратите внимание, что это было с 3 датами. 5 полос появляются. Кажется, что прокрутка вперед и назад добавляет полосы, как будто cellForItemAt вызывается не в той ячейке? Я не совсем уверен.
Любые советы о том, что я делаю неправильно в этой реализации, были бы потрясающими.
Изменить: я добавил этот метод в свой пользовательский класс ячейки:
override func prepareForReuse() {
super.prepareForReuse()
for each_view in self.subviews {
print("Cleared!")
each_view.backgroundColor = UIColor.clear
}
}
Та же проблема все еще возникает, особенно с очень большим диапазоном времени и / или быстрой прокруткой
1 ответ
Не похоже, что вы на самом деле сбрасываете содержимое ячеек, которые возвращаются вам dequeueReusableCell
,
dequeueReusableCell
предоставляет ячейку, которая, возможно, уже использовалась для оптимизации производительности. Документация по методу примечания:
Если существующая ячейка была доступна для повторного использования, этот метод вызывает ячейку
prepareForReuse()
метод вместо.
Если вы посмотрите документацию для prepareForReuse()
, вы обнаружите, что у вас есть шанс сбросить свойства ячейки, чтобы вы могли использовать ячейку повторно.
Если вы сбросите ячейку, вы, вероятно, обнаружите, что она начинает вести себя так, как вы ожидаете.