Почему CollectionViewCell работает со сбоями при прокрутке вверх и вниз? - PullRequest
0 голосов
/ 18 октября 2018

Проблема

При прокрутке вверх и вниз в моей (программно) созданной коллекции View, кажется, ячейки не удаляются должным образом.Это приводит к дублированию его содержимого.

Видео

Ошибка репликации

Желаемое поведение

Я хочу, чтобы ячейки корректно удалялись из очереди, а содержимое не получалодублируется.

Фрагмент кода

Фрагменты кода предоставляются через Pastebin ниже.Мне пришлось добавить некоторый код, чтобы удовлетворить редактор уценки здесь, на SO ...

open class CollectionDataSource<Provider: CollectionDataProviderProtocol, Cell: UICollectionViewCell>: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout where Cell: ConfigurableCell, Provider.T == Cell.T {

https://pastebin.com/CzHYxTDD

class ProductCell: UICollectionViewCell, ConfigurableCell {
}

https://pastebin.com/9Nkr3s4B

Если что-то еще нужно, пожалуйста, спросите в комментариях.

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Проблема

Каждый раз, когда я звоню:

func configure(_ item: ProductViewModel, at indexPath: IndexPath) {
    setupProductImage(with: item.productImage)
    setupStackView()
    setupProductLines(with: item.productLines)
}

, я создаю новый экземпляр productLineLabel = UILabel (), поэтому он будет дублироваться каждый раз при конфигурировании (_ item :)вызывается из cellForRowAtIndexPath.

Решение

Я использовал prepareForReuse, рекомендованный llb для удаления подпредставлений, относящихся к классу UIStackview (содержащих UILabels).Я написал следующее расширение, чтобы сделать это менее утомительным:

func addSubviews(with subviews: [UIView], in parent: UIView) {
    subviews.forEach { parent.addSubview($0) }
  }

Реализация

Единственное, что осталось сделать, - это вызвать пользовательскую функцию расширения из prepareForReuse, например, так:

  override func prepareForReuse() {
    let foundStackView = subviews.filter({$0.isKind(of: UIStackView.self)})[0] as? UIStackView
    guard let labels = foundStackView?.arrangedSubviews.filter({$0.isKind(of: UILabel.self)}) else { return }
    foundStackView?.removeArrangedSubviews(labels, shouldRemoveFromSuperview: true)
  }

Кредиты перейдут на llb, см. Комментарии ниже!<3 Спасибо. </p>

0 голосов
/ 18 октября 2018

Каждый раз, когда вы звоните

func configure(_ item: ProductViewModel, at indexPath: IndexPath) {
    setupProductImage(with: item.productImage)
    setupStackView()
    setupProductLines(with: item.productLines)
}

Вы создаете новый экземпляр productLineLabel = UILabel() внутри setupProductLines() и добавляете его к stackView

. Вы должны изменить это поведение или, скорее, очиститьпредставление стека в методе prepareForReuse.

Имейте в виду, что addArrangedSubview увеличивает количество сохраняемых suview для вновь добавленных элементов.Если вы остановите выполнение своих приложений с помощью кнопки Debug View Hierarchy (рис. 1), скорее всего, вы увидите больше меток, чем ожидаете в ячейке.

fig 1 рис 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...