如何移除UITableView特定索引之后的Cell并解决滚动异常问题
问题根因
你在cellForRowAt方法中直接修改tableView.rowHeight是错误的,这个属性是UITableView的全局行高配置,一旦赋值会作用于所有未单独指定行高的cell,滚动时cell复用触发该方法执行,就会把全局行高改成0,导致所有cell高度异常。另外通过cell.isHidden = true隐藏cell的方案也不符合tableView的设计规范,容易出现复用混乱。
解决方案
方案1:调整数据源数量(最优方案)
你不需要返回self.time.count作为行数,直接过滤出需要展示的元素作为数据源即可,多余的行压根不会创建,从根源避免多余cell展示:
- 数据加载完成后提前处理数据源:
// 只保留需要展示的时间项 self.filteredTimeArr = self.time.filter { sortedTimeArr.contains($0) }
- 修改行数返回逻辑:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.filteredTimeArr.count }
cellForRowAt中直接取过滤后的数据源渲染即可,不需要再做隐藏、设0高度的逻辑,所有展示的cell都是有效内容。
方案2:单独指定行高(适配需保留原数据源索引的场景)
如果你需要保留原数据源的索引对应关系,不能过滤数据源,就实现heightForRowAt代理方法单独给不需要展示的行返回0高度,不要在cellForRowAt里修改全局属性:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if !self.sortedTimeArr.contains(self.time[indexPath.row]) { return 0 } // 正常行高,自适应高度可返回UITableView.automaticDimension return 80 }
同时删除cellForRowAt里的以下错误代码:
tableView.rowHeight = 0 cell.isHidden = true
额外优化:去掉列表底部多余空白cell
如果要彻底清除列表底部无内容的占位cell,直接给tableView设置空的尾视图即可:
tableView.tableFooterView = UIView()
所有配置修改完成后,调用tableView.reloadData()刷新列表即可生效。
内容的提问来源于stack exchange,提问作者Fiaz Hussain
相关产品推荐
相关产品推荐

