ios - 点击时更改和保持 UICollectionView 单元格大小

标签 ios swift uicollectionview uicollectionviewcell uicollectionviewlayout

我正在开发一个使用自定义 FlowLayout 的项目,我无法真正触摸它,但我确实需要扩展用户点击它的单元格的 sidth,因此它占用了 CollectionView 边界的整个宽度,并且还保留了该更改在 viewController 的整个生命周期中,无论 CollectionView 是如何滚动的。

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

以下是更多细节:

我有一个用于 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 在 collectionview 上执行批量更新

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具有存储在 Collection View 中的信息的属性。

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

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

关于ios - 点击时更改和保持 UICollectionView 单元格大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61710647/

相关文章:

ios - 无法点击 UITableView 中的红色减去删除按钮

android - 对于有这么多数据的东西,JSON 比 XML 好吗 "classification"

swift - 为什么我不能将 Int 类型的枚举大小写在单引号中?

ios - 如何在 Swift 中将核心数据属性设置为 nil?

ios - Swift 4 - 如何从 UICollectionViewCell 中嵌套的按钮以编程方式激活 segue

ios - 如何防止collectionView :didSelectItemAtIndexPath delegate method called more than once

ios - UICollectionView 给出 "Index out of range"错误

ios - 使用${PODS_ROOT}后,在SWIFT中导入第三方库时仍然无法得到提示

ios - 如何在ios上实现非全屏文件预览

Swift:ViewModel 应该是结构体还是类?