更改和持久化 UICollectionView Cell Size on Tap

Changing and persisting UICollectionView Cell Size on Tap

我正在开发一个使用自定义 FlowLayout 的项目,我无法真正触摸它,但我确实需要扩展用户点击它的单元格的宽度,以便它占据 CollectionView 边界的整个宽度并且还在整个 viewController 的生命周期中坚持这种变化,不管 CollectionView 是如何滚动的。

现在我已经设法让单元格在点击时展开,但是如果你在集合视图中滚动足够多,如果你向后滚动,单元格会缩小到它的原始大小。现在我认为这是由于单元重用而发生的,但我不知道如何为这种行为建模。

这里有更多详细信息:

我有一个用于 Cell 的 XIB

在 sizeForItem 我有:

      guard let cellViewModel = viewModel?.getCellViewModel(forIndexPath: indexPath) else {
            return CGSize(width: collectionView.frame.width, height: 100)
        }

        var font = UIFont.systemFont(ofSize: 16, weight: .medium)
        var fontAttributes = [NSAttributedString.Key.font: font]
        let nameText = cellViewModel.variationName
        let nameSize = (nameText as NSString).size(withAttributes: fontAttributes)

        font = UIFont.systemFont(ofSize: 16)
        fontAttributes = [NSAttributedString.Key.font: font]
        let priceText = cellViewModel.priceString ?? ""
        let priceSize = (priceText as NSString).size(withAttributes: fontAttributes)

        let contentWidth = nameSize.width + priceSize.width + 38 + 1

        let insetsTotal = collectionView.contentInset.left
        + collectionView.contentInset.right
        + collectionView.safeAreaInsets.right
        + collectionView.safeAreaInsets.left

        var defaultWidth: CGFloat {
            if contentWidth > collectionView.frame.width {
                return collectionView.frame.width - insetsTotal
            } else {
                return contentWidth
            }
        }

      guard let isCellSelected = collectionView.cellForItem(at: indexPath)?.isSelected else { return CGSize(width: defaultWidth, height: 33) }

        var currentWidth = defaultWidth

        if isCellSelected {
            currentWidth = collectionView.frame.width - insetsTotal
        } else {
            currentWidth = defaultWidth
        }

        let size = CGSize(width: currentWidth, height: 33)

        return size
    }

然后我让 didSelectItemAt 和 didDeselectItemAt 对集合视图执行批量更新


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){         collectionView.performBatchUpdates(nil, completion: nil)
 }

 func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath {        collectionView.performBatchUpdates(nil, completion: nil)
    }

我得到的行为是一个很好的扩展单元格,它实际上看起来是动画的,但宽度在滚动时没有保留。 collection-view 有多个部分,所以如果您向下滚动到不同的部分并在那里计时项目,那么上一部分的一些展开的单元格将按比例缩小。我认为这是由于单元重用位,我真的需要一些帮助!

你有这样一行:

let isCellSelected = collectionView.cellForItem(at: indexPath)?.isSelected

但是当单元格准备重用时,CollectionView 更新 isSelected 属性 使用存储在集合视图中的信息。

检查具有给定 indexPath 的单元格是否被选中的正确方法:

let isCellSelected = (collectionView.indexPathsForSelectedItems ?? []).contains(indexPath)