如何在PopoverViewController展示后动态修改其尺寸(含动画)?
解决Popover中UITableView单元格展开的尺寸适配问题
嘿,我明白你遇到的问题了——你想让popover跟着展开的单元格动态调整尺寸,但之前的preferredContentSize设置没生效对吧?问题出在你重写的preferredContentSize逻辑上,咱们一步步来修复:
问题根源
你之前的preferredContentSize的get方法是固定返回46 * actions.count +64,不管单元格有没有展开,所以哪怕你在点击后设置新值,系统读取的还是原来的固定计算结果,自然不会有尺寸变化。
解决方案步骤
1. 添加状态变量跟踪展开的单元格
首先,咱们需要一个变量记录哪个单元格处于展开状态:
var expandedIndexPath: IndexPath? // 定义普通单元格和展开后的高度 let normalCellHeight: CGFloat = 46 let expandedCellHeight: CGFloat = 92 // 你可以根据需求调整这个值
2. 动态计算PreferredContentSize
修改preferredContentSize的重写逻辑,根据展开状态计算总高度:
override var preferredContentSize: CGSize { get { var totalHeight: CGFloat = 64 // 导航栏高度,根据你的实际情况调整 // 遍历所有条目,累加对应高度 for row in 0..<actions.count { let currentIndexPath = IndexPath(row: row, section: 0) totalHeight += (expandedIndexPath == currentIndexPath) ? expandedCellHeight : normalCellHeight } return CGSize(width: view.frame.width, height: totalHeight) } set { super.preferredContentSize = newValue } }
3. 让TableView返回正确的单元格高度
实现heightForRowAt方法,确保单元格能根据展开状态显示对应高度:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return expandedIndexPath == indexPath ? expandedCellHeight : normalCellHeight }
4. 处理单元格点击事件,带动画更新尺寸
在didSelectRowAt里切换展开状态,刷新单元格并触发popover尺寸的动画更新:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) // 切换当前行的展开状态 expandedIndexPath = (expandedIndexPath == indexPath) ? nil : indexPath // 刷新当前行,展示高度变化动画 tableView.reloadRows(at: [indexPath], with: .automatic) // 带动画更新popover尺寸 UIView.animate(withDuration: 0.3) { // 主动触发preferredContentSize的更新 self.preferredContentSize = self.preferredContentSize // 强制containerView布局,让动画更流畅 self.popoverPresentationController?.containerView?.layoutIfNeeded() } }
额外提示
- 如果你的导航栏高度不是64,记得调整
totalHeight的初始值; - 要是需要支持多行展开,只需要把
expandedIndexPath改成Set<IndexPath>,遍历的时候判断是否包含即可; - 确保你的TableView没有设置固定的
rowHeight,或者已经实现了heightForRowAt方法,否则单元格高度不会变化。
这样修改后,点击单元格时,不仅单元格会展开/收起,popover的尺寸也会跟着平滑地调整啦!
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

