ios - 当您的数据源是 Results 对象时,如何在表格视图中移动行?
问题描述
我有一个从结果对象中提取数据的表视图。但是,因为您不能在 Results 对象中移动项目,所以我必须使用 List 对象在表视图中移动行。
但是,如果您将数据从 Results 转换为 List 对象(将 List 对象用于表格视图),则 List 对象不再是反应式的。这意味着它只包含 Results 对象中的数据副本。
所以我的问题是:当您的表格视图从结果对象中提取数据时,您如何在表格视图中移动行?
解决方案
您需要为模型添加索引属性。要么,要么您需要定义一个新的 Realm 类,该类具有索引属性和对您要定义的对象的引用。我会推荐第一个,因为它更简单。这是执行此操作的一种方法。
我会实现一个协议,以便您可以将相同的逻辑应用于其他模型。
protocol IndexableObject: AnyObject {
var index: Int { get set }
}
现在符合协议。
class MovingObject: Object, IndexableObject {
@objc dynamic var name: String = ""
@objc dynamic var index: Int = 0
}
如果您向结果添加扩展名,那将会很有帮助。基本上你想要做的是提取索引在 [fromIndex, toIndex] 范围内的元素并将它们存储在一个数组中,这样你就可以在执行“移动”后更新索引。过滤器确保您只更新必要的索引,而不是结果集中的所有元素。
extension Results where Element: IndexableObject {
func moveObject(from fromIndex: Int, to toIndex: Int) {
let min = Swift.min(fromIndex, toIndex)
let max = Swift.max(fromIndex, toIndex)
let baseIndex = min
var elementsInRange: [Element] = filter("index >= %@ AND index <= %@", min, max)
.map { $0 }
let source = elementsInRange.remove(at: fromIndex - baseIndex)
elementsInRange.insert(source, at: toIndex - baseIndex)
elementsInRange
.enumerated()
.forEach { (index, element) in
element.index = index + baseIndex
}
}
}
您的 UIableViewController 中的用法会像这样。
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let realm = try! Realm()
try! realm.write {
objects.moveObject(from: sourceIndexPath.row, to: destinationIndexPath.row)
}
}
只需确保按索引排序并将对象链接到通知块中的 UITableView 即可。您应该在 Realm 的在线文档中找到有关如何完成此操作的大量信息。
lazy var objects: Results<MovingObject> = {
let realm = try! Realm()
return realm.objects(MovingObject.self)
.sorted(by: \.index, ascending: true)
}()
func observeObjects() {
notificationToken = objects.observe { [weak self] change in
self?.processChange(change)
}
}
推荐阅读
- javascript - 没有 javascript 的 HTML 标签常量
- java - Bazel 构建 java 演示:构建正常但无法运行
- css - Ionic v4 ion-img 急切地加载图像而不是延迟加载
- opengl - 使用足够大的 SSBO 时,着色器程序上的操作会冻结 GL 上下文
- node.js - 两个集合之间的引用在 MongoDB 上不起作用
- php - 单击按钮后将数据库的值更改为当前日期和时间
- python - 使用 MoviePy 或 FFmpeg 连接 Python 列表中的电影
- python - 使用 Sklearn 按月进行在线逻辑回归
- python - 计算巨大稀疏矩阵的点积时的 MemoryError
- javascript - 在放弃更改时,复选框仍然具有相同的状态