You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何为CollectionViewCell内的可折叠TableView添加展开/折叠动画?

Swift中如何为CollectionViewCell内的可折叠TableView添加展开/折叠动画?

我帮你分析下问题所在,然后给出几个关键的修改点,应该能实现类似FotMob的流畅动画效果:

  • 替换无动画的重载方式
    你现在用了.none作为重载动画类型,这当然不会有任何动画效果啦!把它换成系统自动适配的.automatic,或者你也可以试试.top、.fade这类更贴合展开/折叠场景的动画类型:
tableView.reloadSections([indexPath.section], with: .automatic)
  • 修正值类型数据的状态更新(如果你的Section是struct的话)
    如果你的Section是结构体(值类型),直接通过下标修改isOpened是不会生效的——因为下标返回的是结构体的副本,修改副本不会影响原数组里的元素。你需要先取出副本,修改后再赋值回去:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.row == 0 {
        // 先取出对应的section副本
        var currentSection = sections[indexPath.section]
        // 切换展开状态
        currentSection.isOpened.toggle()
        // 把修改后的副本放回数组
        sections[indexPath.section] = currentSection
        // 带动画重载section
        tableView.reloadSections([indexPath.section], with: .automatic)
        // 后续还要处理CollectionViewCell的高度更新,往下看
    }
}
  • 让CollectionViewCell自适应TableView的高度变化
    因为你的TableView嵌套在CollectionViewCell里,当TableView展开/折叠时,它的内容高度会变化,这时候必须让CollectionViewCell跟着调整高度,否则动画会显得很奇怪(比如内容被截断或者Cell高度没变化导致的空白)。

    1. 给CollectionViewCell里的TableView设置完整约束:将TableView的top、leading、trailing、bottom四个约束都绑定到Cell的contentView上,确保TableView的高度完全决定Cell的高度。
    2. 给CollectionView设置自动尺寸:
    // 在CollectionView的布局设置里
    if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        flowLayout.itemSize = UICollectionViewFlowLayout.automaticSize
    }
    
    1. 在TableView完成重载后,通知CollectionView更新对应的Cell布局:
    // 接上面的didSelectRowAt代码
    tableView.reloadSections([indexPath.section], with: .automatic)
    
    // 找到当前TableView所在的CollectionViewCell
    guard let containerCell = tableView.superview?.superview as? YourCollectionViewCellClass else { return }
    guard let collectionView = containerCell.superview as? UICollectionView else { return }
    guard let cellIndexPath = collectionView.indexPath(for: containerCell) else { return }
    
    // 让CollectionView批量更新这个Cell的布局,保证高度自适应
    collectionView.performBatchUpdates({
        collectionView.reloadItems(at: [cellIndexPath])
    }, completion: nil)
    
  • 优化TableView的行高设置
    你的heightForRowAt用固定值没问题,但可以给TableView设置estimatedRowHeight来提升动画流畅度:

// 在TableView初始化或者cell配置时
tableView.estimatedRowHeight = 95 // 取70和120的平均值即可
tableView.rowHeight = UITableView.automaticDimension // 你用了固定行高,这行也可以保留,不影响效果

按照上面的步骤修改后,你的折叠/展开动画应该就能和FotMob的效果类似了,重点是要保证数据状态正确更新、用对动画类型,并且让CollectionViewCell能跟随TableView的高度变化而调整。

备注:内容来源于stack exchange,提问作者Kristoffer Melen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 11:09:40