使用UIStackView实现可展开UITableViewCell时动画异常求助
嘿,我看你在做可展开折叠的TableViewCell时遇到了视图覆盖、动画拉胯的问题,咱们来一步步搞定它~
首先拆解下核心问题:你的动画效果差、视图重叠,主要是因为动画时长设为0、用alpha而非isHidden控制布局空间,以及没让TableView正确感知Cell的高度变化。下面是具体修复方案:
1. 修正TableView的didSelectRowAt方法
把动画时长改成合理值(比如0.3),同时用状态属性管理展开/收起逻辑,让TableView能正确触发高度更新:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("tap") guard let cell = tableView.cellForRow(at: indexPath) as? TableViewCell else { return } // 切换展开状态 cell.isExpanded = !cell.isExpanded // 用动画包裹TableView更新,实现平滑高度变化 UIView.animate(withDuration: 0.3) { tableView.beginUpdates() tableView.endUpdates() } }
2. 重构Cell的展开/收起逻辑
删掉复杂的关键帧动画,利用UIStackView的特性——当arrangedSubview的isHidden设为true时,StackView会自动移除它的布局空间,从而让Cell高度自动变化:
class TableViewCell: UITableViewCell { @IBOutlet weak var stufView: UIView! // 新增状态属性,自动同步视图显示状态 var isExpanded = false { didSet { stufView.isHidden = !isExpanded } } }
为什么不用alpha?因为alpha只是改变视图透明度,视图依然占据原布局空间,TableView无法感知Cell高度变化,自然会出现下方Cell覆盖的问题。而isHidden会让UIStackView自动收缩,TableView就能通过beginUpdates()/endUpdates()实现平滑的高度动画。
3. 开启TableView自动高度计算
在ViewController的viewDidLoad里设置:
override func viewDidLoad() { super.viewDidLoad() tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 100 // 设一个接近默认Cell高度的预估数值 }
这一步是关键,只有开启自动高度,TableView才能根据Cell内容动态计算高度,配合动画实现流畅的展开折叠效果。
4. 检查Storyboard布局
从你的截图来看,要确保stufView是UIStackView的arrangedSubview,并且StackView已经和Cell的contentView绑定了正确的约束(比如上下左右无冲突约束)。这样当stufView隐藏时,StackView会自动收缩,Cell高度也会同步变化。
做完这些修改后,展开折叠的动画就会变得平滑,再也不会出现下方视图覆盖上方的问题啦~
内容的提问来源于stack exchange,提问作者Manki

