You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realm填充的TableView删除单元格后,最后单元格跳转至被删位置求助

问题原因及解决方案

这个问题我做Realm+UITableView开发时也碰到过,核心原因是你用了tableView.reloadData()全量刷新列表,再加上Realm Results的自动更新特性,导致TableView无法正确处理单元格的位置动画,才出现最后一个单元格跳转到被删除位置的奇怪现象。

具体原因拆解:

  • Realm Results的自动更新特性:你通过realm.objects(Times.self)获取的Results是一个实时自动同步的集合,当你删除其中的对象后,这个集合会自动更新,根本不需要手动调用loadTimes()去重新获取数据,你的loadTimes()方法反而会强制TableView重新加载所有数据,打乱了它的状态管理。
  • 全量刷新的弊端:tableView.reloadData()会让TableView直接重置所有单元格,它无法感知到具体是哪一行被删除,所以在重新渲染时会出现位置计算错误,导致最后一个单元格“跳”到被删除的位置。

修复方案(修改你的代码):

只需要调整tableView(_:commit:forRowAt:)方法,移除loadTimes()的调用,改用UITableView的批量删除API来处理:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        // 先执行Realm数据删除
        self.updateModel(at: indexPath)
        // 通知TableView精确删除对应行,使用系统动画过渡
        tableView.deleteRows(at: [indexPath], with: .automatic)
    }
}

// 保留你的updateModel方法,不需要改动
func updateModel(at indexpath: IndexPath) {
    if let itemForDeletion = results?[indexpath.row] {
        do{
            try self.realm.write {
                self.realm.delete(itemForDeletion)
            }
        } catch {
            print("Error saving context \(error)")
        }
    }
}

// 可以移除loadTimes()方法,或者只在初始化时调用一次(比如viewDidLoad里)

额外注意事项:

  • 确保你的results是类级别的属性,这样才能保持和Realm数据库的实时绑定,数据变化时它会自动更新。
  • 如果后续需要监听Results的其他变化(比如其他页面修改了数据),可以使用Realm的NotificationToken来监听集合变化,然后再针对性地更新TableView,而不是全量刷新。

内容的提问来源于stack exchange,提问作者M. Gabriel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:34:55