Swift中如何正确展开UITableView的最后一个UITableViewCell?
UITableView可展开单元格实现方案(基于栈视图元素显隐)
我最近做了一个带可展开/收起功能的UITableView,每个单元格的核心结构是一个栈视图,通过控制栈内部分元素的显隐来实现展开收起的交互,先给大家看预期的交互效果:
下面是我用来处理单元格展开收起、动态调整行高的核心代码片段:
func expandCell(_ cell: MyCell) { guard let arrowButton = cell.arrowUpDownButton else { return } if arrowButton.isSelected { // 执行收起动画:先让隐藏区域透明,完成后再设置isHidden UIView.animate(withDuration: 0.2, animations: { cell.stackHides.alpha = 0 }) { [weak self] _ in arrowButton.isSelected = false cell.stackHides.isHidden = true // 通知tableView更新行高,触发平滑动画 self?.tableView.beginUpdates() self?.tableView.endUpdates() } } else { // 执行展开逻辑:先显示隐藏区域,再做淡入动画 arrowButton.isSelected = true cell.stackHides.isHidden = false UIView.animate(withDuration: 0.2) { cell.stackHides.alpha = 1 } // 刷新行高,让单元格自适应展开后的高度 tableView.beginUpdates() tableView.endUpdates() } }
这里有几个关键细节要注意:
- 动画完成后再设置
isHidden = true:如果只设置alpha为0,元素依然会占据布局空间,导致单元格行高不会正确收缩 - 使用
beginUpdates()+endUpdates()更新行高:这组方法会让tableView平滑地调整行高,比直接调用reloadRows的过渡效果更自然 - 用
[weak self]捕获self:避免因为闭包持有导致的循环引用,防止内存泄漏 - 确保单元格约束正确:
stackHides的高度要自适应内部内容,这样单元格的intrinsicContentSize才能随着元素显隐自动变化,tableView才能正确计算行高
内容的提问来源于stack exchange,提问作者Sergio
相关产品推荐
相关产品推荐

