Каждый раз, когда ваша клетка вызывается, вызывается cellForItemAt
. Это место, где вы настраиваете данные своей ячейки. Поэтому, если вам нужно показать ячейку, отмеченную как избранное, вы можете сделать это здесь.
Так как ты там делаешь? Допустим, все ваши клетки не выделены в начале. Хорошо. Вам не нужно ничего говорить в cellForItemAt
. Допустим, вы отметили несколько ячеек как избранные. Здесь происходит то, что оно будет отражать изменение, когда ячейка видна, потому что кнопка подключена к селектору, который внесет изменения.
Теперь вот проблема. Когда вы прокручиваете и ячейка исчезает, информация о том, что ваша ячейка помечена как любимая, теряется! Итак, вам нужно сохранить массив, в котором будут храниться IndexPath
всех выбранных ячеек. (Обязательно удалите IndexPath
при удалении ячейки из избранного!) Давайте назовем этот массив favourites
. Если вы можете использовать свой источник данных для представления коллекции, чтобы сохранить выбранную информацию о состоянии, это тоже хорошо. Теперь вам нужно сохранить информацию о том, помечена ли ваша ячейка как избранная в селекторе кнопок.
@objc func buttonTapped() {
if favourites.contains(indexPath) { // Assuming you store indexPath in cell or get it from superview
favourites.removeAll(where: {$0 == indexPath})
} else {
favourites.append(indexPath)
}
}
После того, как вы сохранили информацию о ячейке, каждый раз, когда вы снимаете ее, вы должны проверить, является ли IndexPath
favourites
. Если это так, вы вызываете метод, который устанавливает ячейку в выбранное состояние.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// Dequeue cell and populating cell with data, etc
if favourites.contains(indexPath) {
cell.showFavourite()
}
}
Готово? Нет! Теперь у нас есть другая проблема. Эта проблема связана с повторного использования ячейки. Так что же на самом деле происходит в cellForItemAt
? Вы снимаете ячейку и используете ее для отображения информации. Таким образом, когда вы удаляете это, то, возможно, это уже использовалось для показа некоторой другой информации в каком-то другом пути индекса. Таким образом, все существующие там данные будут сохраняться . (Вот почему у вас есть проблема повторения избранного через каждые 4 ячейки!)
Так, как мы решаем это? В UICollectionViewCell
есть метод, который называется до , когда ячейка отключается - prepareCellForReuse
. Вам нужно реализовать этот метод в своей ячейке и удалить всю информацию из ячейки, чтобы она была свежей, когда она достигает cellForItemAt
.
func prepareForReuse() {
//Remove label text, images, button selected state, etc
}
Или вы всегда можете установить каждое значение всего внутри ячейки в cellForItemAt
, чтобы каждая информация всегда перезаписывалась необходимым значением.
Редактировать: OP говорит, что у него есть представление коллекции внутри представления коллекции. Вы можете определить, какое представление коллекции называется так,
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView === favoriteCollectionView { // This is the collection view which contains the cell which needs to be marked as favourite
// Dequeue cell and populating cell with data, etc
if favourites.contains(indexPath) {
cell.showFavourite()
}
return cell
}
// Dequeue and return for the other collectionview
}