首页 > 解决方案 > 防止 sizeForItemAt 因重复使用动态 collectionView 单元格而使用错误的单元格大小

问题描述

我使用自动布局来动态计算 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。当我滚动到其余部分时(第一部分将不可见并且单元格将被重用),第二部分和第三部分中的一些单元格在第一次滚动到视口而不是 104 时使用值 88.0 作为单元格的高度. 当我继续滚动时,错误大小的单元格将使用 104 作为维度。我们如何强制所有单元格重新计算高度并且不使用旧单元格的高度。

标签: iosswiftautolayoutuicollectionviewcell

解决方案


您的想法是正确的,但是当您通过调用来测量单元格的内部约束时systemLayoutSizeFitting,而不是调用systemLayoutSizeFitting现有单元格 ( ),您需要使用您配置的模型单元格来武装自己,就像配置它并测量一样.collectionView.cellForItemcellForItem

这是我的做法(与您所拥有的非常相似,但有一点不同;另外,我将尺寸存储在模型中):

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
}

推荐阅读