iOS (Swift): представление коллекции IndexPath (для: ячейка) - ноль для невидимой ячейки - PullRequest
0 голосов
/ 07 июня 2018

У меня есть UIViewController, который заполняет UICollectionView массивом типа Object:

class MyViewController: UIViewController {

    let objects: [Object]!

    weak var collectionView: UICollectionView!

    func object(for cell: MyCell) {
        guard let indexPath = self.collectionView.indexPath(for: cell) else { fatalError("No cell at index path") }
    }

}

Ячейки collectionView представлены как:

class MyCell: UICollectionViewCell {

    weak var delegate: MyCellDelegate?

    override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
        super.apply(layoutAttributes)

        let obj = self.delegate?.object(for: self)
        // configure various subviews with obj ...

    }
}

который имеет delegate, который обращается к MyViewController, чтобы получить экземпляр Object, который представляет:

protocol MyCellDelegate: class {
    func object(for cell: MyCell) -> Object
}

Это прекрасно работает, когда я прокручиваю вниз между ячейками, однако он падает на guard let indexPath = self.collectionView.indexPath(for: cell) ...для ячеек, которые находятся вне экрана при вызове метода apply(_ layoutAttributes: UICollectionViewLayoutAttributes).

Есть ли способ исправить это?Ячейки должны знать, какой экземпляр Object они представляют, чтобы контроллер представления мог настроить модель.

Большое спасибо за любую помощь!

1 Ответ

0 голосов
/ 07 июня 2018

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

Для выполнения некоторых действий вне экрана я часто держу отдельный объект (модель представления в MVVM), к которому видимая ячейка может присоединиться,Этот объект принадлежит и хранится моими объектами и никогда не используется повторно.Если мне нужно выполнить какое-либо закадровое действие, этот объект сделает это.

Единственными заданиями ячейки являются:

  1. для отображения данных и
  2. для получения ввода пользователя

Оба требуют, чтобы он был видимым.

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

Альтернативное решение

Если все, что вам нужно, это путь индекса для получения вашего специального объекта, вы можете просто использовать путь индекса из атрибутов макета.

protocol MyCellDelegate: class {
    func object(for indexPath: IndexPath) -> Object
}

class MyCell: UICollectionViewCell {

    weak var delegate: MyCellDelegate?

    override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
        super.apply(layoutAttributes)

        let obj = self.delegate?.object(for: layoutAttributes.indexPath)
        // configure various subviews with obj ...

    }
}
...