我在Realm中使用了以下对象模式(我使用Typescript符号描述它,因为我对它很熟悉):
Publisher {
name: String (primary key),
position: Int,
games: RealmSwift.List<Game>,
}
Game {
name: String (primary key),
description: String,
cover: String,
position: Int,
}
字符串
因此,每个发行商都有自己的游戏列表,并且onAppear位于ContentView的最外层视图。swift我从Realm加载所有发行商,并按position
keyPath对其进行排序。但是,我也希望games
列表按position
对每个发布者进行排序,我不确定您是否可以直接这样做。下面是我在onAppear
方法下编写的代码:
ContentView.swift相关部分:
import SwiftUI
import RealmSwift
struct ContentView: View {
@State var publishers: Results<Publisher>? = nil
private var realm: Realm
init() {
self.realm = try! Realm()
}
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading, spacing: 10) {
if publishers != nil {
ForEach(publishers!, id: \.name) { publisher in
PublisherName(publisher: publisher.name)
List {
ForEach(publisher.games, id: \.name) { game in
HStack {
Text(String(game.position))
.font(.system(size:20))
.fontWeight(.bold)
GameRow(game: game)
}
}.onMove(perform: {
startIndex, destination in
do {
try self.realm.write {
publisher.games.move(fromOffsets: startIndex, toOffset: destination-1)
}
}catch {
print("Error: \(error)")
}
})
}
}
}
}
}
.onAppear(perform: {
let realm = try! Realm()
self.publishers
= realm.objects(Publisher.self)
.reduce(RealmSwift.List<Publisher>(), { publishersList, publisher -> RealmSwift.List<Publisher> in
let p = Publisher()
p.name = publisher.name
p.position = publisher.position
p.games = publisher.games.sorted(byKeyPath: "position")
.reduce(RealmSwift.List<Game>(), { gamesList, game -> RealmSwift.List<Game> in
gamesList.append(game)
return gamesList
})
publishersList.append(p)
return publishersList
})
.sorted(byKeyPath: "position")
})
}
}
}
型
当我运行上面的代码时,我在@main得到以下错误,显然是由onAppear
块中的代码引起的(因为如果我删除它,一切都正常):
"This method may only be called on RLMArray instances retrieved from an RLMRealm"
型
此外,我想当在编辑模式下,在交换两个游戏的位置,变化应该写在境界数据库,并立即在我的应用程序更新,因为我想“重新加载”的变化。实际上,它已经在Realm上写入了更改,但除非我重新加载视图,否则更改不会发生,例如切换编辑模式。
2条答案
按热度按时间yc0p9oo01#
这是绝对可行的。假设您有两个这样的模型,您应该能够在更新模型对象的位置属性时添加、删除和移动行。我经常这样。
让我们假设您的模型对象如下所示:
字符串
现在,让我们创建一个定义
position
属性的协议。型
现在让我们让我们的模型符合它:
型
这个
Results
扩展将允许我们“移动”按position
排序的对象。这意味着它将更新所有需要更新的元素的position
属性。请记住,这要求您的结果集已经按位置排序。型
现在,我们需要对
List
执行类似的操作。这个方法稍微简单一点,因为List提供了一个move(fromOffsets: toOffsets:)
方法。但是,您还记得,您还需要更新所有受影响元素的position
属性。型
让我们添加一个delete方法来更新
position
属性。现在我们可以在List
和Results
上使用此方法,因为它们都符合RealmCollection
。同样,此方法假定集合已按position
排序。型
至于UI,请确保对
Results<Publisher>
属性使用@ObservedResults
属性 Package ,对Publisher
属性使用@ObservedRealmObject
属性 Package 。此外,请记住,这些属性 Package 器将冻结所有对象,因此您需要调用
thaw()
以便在任何领域写入之前解冻这些对象。下面是一个UI示例:
型
dldeef672#
如果您已经在使用列表,则可以简单地使用
list.move
。List
存储为对象id数组,因此您可以依赖对象id在数组中的位置。$
将操作 Package 在写事务中。如果您想使用自定义字段来对数据进行排序,here是一些模板代码。如果您使用的是Flexible Sync,则需要处理在2个不同设备上使用相同顺序/位置创建项目的情况。