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高度没变化导致的空白)。- 给CollectionViewCell里的TableView设置完整约束:将TableView的
top、leading、trailing、bottom四个约束都绑定到Cell的contentView上,确保TableView的高度完全决定Cell的高度。 - 给CollectionView设置自动尺寸:
// 在CollectionView的布局设置里 if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout { flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize flowLayout.itemSize = UICollectionViewFlowLayout.automaticSize }- 在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)- 给CollectionViewCell里的TableView设置完整约束:将TableView的
优化TableView的行高设置
你的heightForRowAt用固定值没问题,但可以给TableView设置estimatedRowHeight来提升动画流畅度:
// 在TableView初始化或者cell配置时 tableView.estimatedRowHeight = 95 // 取70和120的平均值即可 tableView.rowHeight = UITableView.automaticDimension // 你用了固定行高,这行也可以保留,不影响效果
按照上面的步骤修改后,你的折叠/展开动画应该就能和FotMob的效果类似了,重点是要保证数据状态正确更新、用对动画类型,并且让CollectionViewCell能跟随TableView的高度变化而调整。
备注:内容来源于stack exchange,提问作者Kristoffer Melen
相关产品推荐
相关产品推荐

