插入/删除TableView行后无法调整contentOffset问题求助
问题原因
- 调用
insertRows后,tableView的行插入、布局更新、自动偏移调整都是异步在当前runloop的下一周期执行的,插入后同步设置的contentOffset会被系统后续的自动调整逻辑覆盖,因此不会生效 - 倒置的tableView在顶部插入新行时,系统默认会自动调整contentOffset保持当前用户可见的内容位置不变,也会覆盖手动设置的偏移值
可行解决方案
方案1:使用performBatchUpdates的完成回调设置偏移
把插入行的逻辑放到performBatchUpdates块中,布局完成后的completion回调里再调整偏移,此时tableView的contentSize和布局已经稳定,设置的偏移不会被覆盖:
self.tableView.performBatchUpdates { // 先更新数据源,再执行插入操作 self.tableView.insertRows(at: [IndexPath(row: index, section: 0)], with: .right) } completion: { [weak self] _ in self?.tableView.contentOffset = CGPoint(x: 0, y: 80) }
方案2:延迟到下一个主队列周期执行偏移设置
如果不想用批量更新的回调,也可以把偏移设置派发到主队列的下一个执行周期,等待tableView的插入布局逻辑完成后再执行:
self.tableView.insertRows(at: [IndexPath(row: index, section: 0)], with: .right) DispatchQueue.main.async { [weak self] in self?.tableView.contentOffset = CGPoint(x: 0, y: 80) }
注意事项
- 如果tableView开启了预估行高
estimatedRowHeight,插入行后系统计算的contentSize可能存在偏差,建议行高固定的话直接设置固定rowHeight,或者在设置偏移前先调用self.tableView.layoutIfNeeded()强制刷新布局 - 倒置tableView的偏移坐标和普通tableView上下翻转,确认设置的y值符合预期,避免偏移方向搞反
内容的提问来源于stack exchange,提问作者Akilan C B
相关产品推荐
相关产品推荐

