数据源为Results对象时,如何实现Table View的行移动操作?
Realm Results 作为 TableView 数据源实现行移动的可行方案
Realm 中的 Results 是动态自更新的只读集合,本身不支持直接修改内部元素的排序,要在保留响应性的前提下实现行移动,核心是让 Results 的排序规则可随用户操作更新,两种主流可行方案如下:
方案1:为数据模型新增排序权重字段,结合排序查询生成
Results
这是生产环境最常用的实现方式,具体步骤:- 给你的数据模型新增一个
sortOrder类型的整数字段,作为排序的权重依据,初始存入数据时按默认顺序赋值即可 - 生成
Results实例时,通过sortDescriptor指定以sortOrder作为排序键,此时得到的Results仍然具备完整响应性,底层数据发生任何变更时都会自动同步更新 - 用户触发行移动操作时,在 Realm 写事务内批量调整对应数据的
sortOrder值即可:比如将第3行移动到第1行,只需把原第1、2行的sortOrder各+1,再将被移动行的sortOrder设为原第1行的sortOrder-1 - 依赖
Results自带的变更通知特性,TableView 会自动刷新对应UI变化,不需要手动维护数据源副本
优势:完全保留Results的响应性、懒加载、低内存占用等所有原生特性,实现逻辑简单,排序状态会持久化存储,App 重启后仍然保留用户调整的顺序
优化点:如果数据量超过万级,可以采用间隔赋值的方式减少写操作开销,比如初始sortOrder的赋值间隔设为100,移动行时直接把目标行的sortOrder设为目标位置前后两个元素的sortOrder中间值,不需要批量调整其他元素的权重,只有间隔不足时再统一重排所有值
- 给你的数据模型新增一个
方案2:搭建
Results与内存排序映射的中间层
如果你不需要持久化用户调整的排序状态,仅需要当前会话内支持行移动,可以采用该方案:- 仍然保留原始
Results作为数据的唯一可信源,监听Results的变更通知,底层数据发生增删改时同步更新内存映射 - 额外维护一个内存数组,存储
Results内所有元素的主键,数组的顺序就是用户调整后的行顺序 - TableView 的所有数据源方法都从这个主键数组取对应索引的主键,再到
Results中按主键查询对应的实体数据使用
优势:不需要修改数据模型,不需要执行持久化写操作,适合临时排序的场景
注意点:需要自己处理Results变更和内存主键数组的同步逻辑,避免出现索引不匹配的错乱问题
- 仍然保留原始
不推荐直接将
Results转换为List作为数据源,这种方式拿到的是静态副本,会丢失Results的自动更新、懒加载等所有原生优势,仅适合数据量极小且不需要响应更新的边缘场景。
内容的提问来源于stack exchange,提问作者Junsu Kim
相关产品推荐
相关产品推荐

