Запретите sizeForItemAt использовать неверный размер ячейки из-за повторного использования для динамической ячейки collectionView - PullRequest
0 голосов
/ 30 мая 2019

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

В моем sizeForItemAt у меня есть следующее:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if let cachedSize = cachedHeightForIndexPath[indexPath] {
            return cachedSize
        }

        if let cell = collectionView.cellForItem(at: indexPath) {
            cell.setNeedsLayout()
            cell.layoutIfNeeded()
            let size = cell.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
            cachedHeightForIndexPath[indexPath] = size
            print("value is \(size) for indexpath: \(indexPath)")
            return size
        }
        return CGSize(width: ScreenSize.width, height: 0.0)
    }

У меня есть три сеанса, с первым разделом высота всех ячеек теоретически равна 88, а все остальные разделы всевысота ячейки равна 104.

Изначально виден только первый раздел.Из консоли видно, что высота ячейки установлена ​​на 88.0, как и ожидалось.Поскольку я прокручиваю до оставшихся разделов (первый раздел будет невидимым, а ячейки будут использоваться повторно), некоторые ячейки из второго раздела и третьего раздела используют значение 88.0 в качестве высоты ячеек при первой прокрутке для просмотра порта вместо 104Поскольку я продолжаю прокручивать, ячейка неправильного размера будет использовать 104 в качестве измерения.Как заставить все ячейки пересчитать высоту и не использовать высоту из старой ячейки.

1 Ответ

1 голос
/ 30 мая 2019

У вас правильная идея, но когда вы измеряете ячейку по ее внутренним ограничениям, вызывая systemLayoutSizeFitting вместо вызова systemLayoutSizeFitting в существующей ячейке (collectionView.cellForItem), вам необходимовооружитесь ячейкой модель , которую вы настроите так же, как настроил бы cellForItem и измерили , что .

Вот как я это делаю (удивительно похоже на то, чтоу вас есть, с этим одним отличием, а также я храню размер в модели):

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let memosize = self.sections[indexPath.section].itemData[indexPath.row].size
    if memosize != .zero {
        return memosize
    }
    self.configure(self.modelCell, forIndexPath:indexPath) // in common with cellForItem
    var sz = self.modelCell.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
    sz.width = ceil(sz.width); sz.height = ceil(sz.height)
    self.sections[indexPath.section].itemData[indexPath.row].size = sz // memoize
    return sz
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...