如何使用SwiftUI选取器将Realm更新为一个关系



我有以下在赛道上进行比赛的领域模式:

final class Race: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var track: Track?
@Persisted var duration: Int = 45
}
final class Track: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name: String = "Imola"
@Persisted var country: String = "🇮🇹"

@Persisted(originProperty: "tracks") var group: LinkingObjects<TrackGroup>
}
final class TrackGroup: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var tracks = RealmSwift.List<Track>()
}

在我的ContentView中,我有一个打开工作表的添加按钮(AddRaceView(。当工作表出现时,新的比赛已经创建。现在,我想使用选择器为我们新创建的比赛选择赛道。

以下代码没有更新可编辑比赛的赛道,我不明白为什么:

struct AddRaceView: View {

@ObservedRealmObject var race: Race
@ObservedRealmObject var trackGroup: TrackGroup

var body: some View {
Form {
chooseTrackSection
raceDurationSection
}
}

@State private var trackPickerVisible = false

var chooseTrackSection: some View {
Section(header: Text("Track")) {
Button {
withAnimation(.easeIn) {
self.trackPickerVisible.toggle()
}
} label: {
HStack {
Text(race.track?.name ?? "")
Spacer()
Image(systemName: "arrow.turn.right.down")
}
}
if trackPickerVisible {
// HERE: Selection is not processed.
Picker(selection: $race.track, label: Text("Track")) {
ForEach(trackGroup.tracks) {
Text($0.name)
}
}
.pickerStyle(.wheel)
}
}
}

更新比赛中的其他值(如持续时间(确实有效!例如,当Track是String时,我可以使用Picker进行选择。这个问题一定与我试图更改Realm对象/关系的事实有关。

需要考虑三件事:

  1. 选取器需要知道在哪里可以找到值。可以通过将.tag(value(添加到元素中手动指定该值。虽然ForEach为符合Identifiable的对象提供了隐式标记,但在您的情况下,类型不匹配(需要是Optional<Track>而不是Track(。

  2. 选取器将所有标记值与所选内容进行比较,以找出当前选择的项目。如果对象不是来自同一个Realm实例,则比较失败。不幸的是,目前没有任何方法可以为ObservedResultsObservedRealmObject指定领域。

  3. 引用冻结领域中的对象不起作用,因此必须先解冻它们(或它们的领域(。

代码:

// Fetch the Tracks from the Race's Realm by finding the TrackGroup by primaryKey
if let tracks = race.realm?.thaw().object(ofType: TrackGroup.self, forPrimaryKey: trackGroup._id)?.tracks {
Picker("Track", selection: $race.track) {
ForEach(tracks) { track in
Text(track.name)
.tag(Optional(track)) // Specify the value, making it optional to exactly match the expected type
}
}
}

相关内容

最新更新