修改 ObservedRealmObject 属性后 SwiftUI 视图未更新

问题描述 投票:0回答:1

我有以下 Realm 对象 - Make 保存模型列表。

class Make: Object, ObjectKeyIdentifiable {
    @Persisted var name: String = ""
    @Persisted var models: RealmSwift.List<Model>
}

class Model: Object, ObjectKeyIdentifiable {
    @Persisted var name: String = ""
    @Persisted var flag: Bool = false
    @Persisted(originProperty: "models") var make: LinkingObjects<Make>
}

我有一个以下视图,它获取所有品牌并将它们呈现在列表中。 点击给定的 Make 将打开一个包含其模型列表的工作表,或者根据部分将相同的视图推送到当前的 NavigationStack 上(这只是为了显示差异)

struct ContentView: View {
    @ObservedResults(Make.self) private var makes
    
    @State private var selected: Make?

    var body: some View {
        NavigationStack {
            List {
                Section {
                    ForEach(makes) { make in
                        Text(make.name)
                            .onTapGesture {
                                selected = make
                            }
                    }
                }
                Section {
                    ForEach(makes) { make in
                        NavigationLink {
                            MakeView(make: make)
                        } label: {
                            Text(make.name)
                        }
                    }
                }
            }
            .sheet(item: $selected) { make in
                MakeView(make: make)
            }
        }
    }
}

MakeView 有一个模型列表,点击模型会打开另一个视图,我们可以在其中编辑模型的名称

struct MakeView: View {
    @ObservedRealmObject var make: Make
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(make.models) { model in
                    NavigationLink {
                        EditModelView(model: model)
                    } label: {
                        HStack {
                            Text(model.name)
                            Spacer()
                            Image(systemName: model.flag ? "checkmark.circle" : "x.circle")
                        }
                    }
                }
            }
        }
    }
}

最后是允许我们编辑模型对象的 EditModelView

struct EditModelView: View {
    @ObservedRealmObject var model: Model

    var body: some View {
        Form {
            TextField(text: $model.name) {
                Text("Name")
            }
            Toggle("Flag", isOn: $model.flag)
        }
    }
}

这里的问题是,如果我通过 .sheet 呈现 MakeView 并转到 EditViewModel,如果我更改 TextField 或 Toggle 中的值并返回到上一个视图 (MakeView),则更改不存在,实际上只存在一个更改。如果我更改“名称”字段中的一个字母,它将被更改,但任何下一个字母都不会出现,当仅反映一个值更改并且任何后续更改都将不可见时,它在切换上会更好地可见。如果我关闭 MakeView 并再次打开它,更改就在那里。因此,数据库已正确更新,但在更改标志的模型名称后视图不会更新。 如果将 MakeView 推送到 NavigationStack 上,则不会出现此问题。 根据我的理解,ObservedObject 应该跟踪更改并相应地更新视图。

我对 SwiftUI 还很陌生,所以我不确定这是否是 RealmSwift 方面的错误,或者我的经验不足,不明白应该如何实现。

swift swiftui realm
1个回答
0
投票

有一些解决方案,但问题是视图没有刷新(并且无法按原样关闭工作表(需要添加)。所以这是基于问题中的代码的an答案,但还有很多其他的。

尝试将代码更改为以下内容(我删除了工作代码部分)

                Section {
                    ForEach(makes) { make in
                        Text(make.name)
                            .onTapGesture {
                                selected = make
                            }
                    }
                }
            }
            .sheet(item: $selected,
                   onDismiss: didDismiss) { make in
                MakeView(make: make)
            }
            .onTapGesture {
                selected = nil
            }
        }
    }

    func didDismiss() {
        // Handle the dismissing action.
    }

请同时查看 ForEach 初始化器

实例仅读取所提供数据的初始值,不需要跨更新识别视图。要在动态范围内按需计算视图,请使用 ForEach/init(_:id:content:)。

© www.soinside.com 2019 - 2024. All rights reserved.