如何在具有动态单元格高度的 UICollectionView 中实现流畅的展开/折叠动画?

How to achieve smooth expand/ collapse animation in UICollectionView with dynamic cell height?

我已经为具有动态单元格高度的UICollectionView实现了展开/折叠动画(因为不同的单元格具有不同的内容)。

这是我的实施总结

  1. 我正在使用 UICollectionViewCompositionalLayout,因为我希望单元格能够调整自己的高度以适应其内容。 ()
  2. 我在单元格中使用 UIStackView。原因是,一旦我在单元格中隐藏了一个 UITextView,我不希望隐藏的 UITextView 仍然占据 space。使用 UIStackView 可以避免我处理零高度限制。
  3. 我正在使用performBatchUpdateslayoutIfNeeded实现动画,基于

这是最终结果 - https://www.youtube.com/watch?v=2uggmpk0tJc

如您所见,整体效果不是很流畅,尤其是当我在 “颜色”“打印 PDF”[=] 之间切换时51=],内容高度更大。

这是我点击单元格时发生的情况

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    var indexPaths = [IndexPath]()
    
    for i in (0..<isExpanded.count) {
        if isExpanded[i] != false {
            isExpanded[i] = false
            
            indexPaths.append(IndexPath(item: i, section: 0))
        }
    }
    
    if isExpanded[indexPath.item] != true {
        isExpanded[indexPath.item] = true
        
        indexPaths.append(IndexPath(item: indexPath.item, section: 0))
    }
    
    collectionView.performBatchUpdates({}) { _ in
        collectionView.reloadItems(at: indexPaths)
        collectionView.layoutIfNeeded()
    }
}

你有什么想法,我还可以尝试什么,让动画看起来更流畅?这是演示的完整代码示例

https://github.com/yccheok/shop-dialog/tree/1a2c06b40327f7a4d6f744f1c3a05a38aa513556

谢谢!

您可以通过将 didSelectItemAt 更改为以下内容来接近您的目标:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    for i in (0..<isExpanded.count) {
        if i == indexPath.item {
            // toggle selected row
            isExpanded[i].toggle()
        } else {
            // set all other rows to false
            isExpanded[i] = false
        }
        if let c = collectionView.cellForItem(at: IndexPath(item: i, section: 0)) as? CollectionViewCell {
            c._description.isHidden = !isExpanded[i]
        }
    }
    collectionView.performBatchUpdates(nil, completion: nil)
    
}

尽管在堆栈视图中显示和隐藏元素时元素的默认动画/压缩并不总是可以接受的。如果你想尝试完善它,看看这个讨论: