以下是我在SwiftUI中测试@Observable
功能的示例实现。它包含简单的列表视图和详细信息视图。
我们可以将对象添加到列表中(它们会反映在视图中)。我们可以转到详细信息查看并编辑名称,描述。但是,这些更改未反映在上一个屏幕(列表)中。
这是不正确的方法,还是仅应使用@EnvirnomentObject
变量来获得所需的结果?
import SwiftUI
struct ContentView: View {
@ObservedObject var model: ModelOne
var body: some View {
NavigationView{
List(){
ForEach(model.items,id: \.id){
item in
NavigationLink(destination: DetailView(item: item)){
VStack(alignment: .leading){
Text(item.name).lineLimit(1)
Text(item.description).lineLimit(1)
}.onAppear {
print("\(item.name)")
}
}
}
}.navigationBarTitle("List", displayMode: .inline)
.navigationBarItems(trailing: AddItem(buttonAction: {
let newItem = Items()
newItem.name = "Empty"
newItem.description = "Empty"
self.model.items.append(newItem)
}))
}
}
}
struct AddItem: View {
var buttonAction: (()->Void)
var body: some View{
Button(action: {
self.buttonAction()
}){
Text("Add")
}
}
}
class ModelOne: ObservableObject{
@Published var items: [Items] = []
}
class Items: Identifiable{
var id: UUID = UUID()
var name: String = ""
var description: String = ""
}
详细视图:
import SwiftUI
struct DetailView: View {
@ObservedObject var item: Items
var body: some View {
VStack{
TextField(item.name, text: $item.name)
TextField(item.description, text: $item.description)
}
}
}
还没有时间进行测试,但是我认为您的“数组”类型没有改变,因此不会触发发布者。另外,您在详细视图中观察到一个项目,但是将更改发布到“数组”上,我认为这行不通。
尝试将观察到的模型传递给详细视图,并为特定项目传递一个附加参数。
body
中的[ContentView
正在观察model
-它未观察到行内的项目,因此对特定Items
的更新不会触发对body
中的ContentView
的更新。
解决此问题的最简单方法是将行移动到自己的struct
中,该行正在观察项目。这样,当项目更改时,行中的视图将被更新:
struct ContentView: View {
@ObservedObject var model: ModelOne
var body: some View {
NavigationView{
List(){
ForEach(model.items,id: \.id){
item in
NavigationLink(destination: DetailView(item: item)){
Row(item:item)
}
}
}.navigationBarTitle("List", displayMode: .inline)
.navigationBarItems(trailing: AddItem(buttonAction: {
let newItem = Items()
newItem.name = "Empty"
newItem.description = "Empty"
self.model.items.append(newItem)
}))
}
}
}
struct Row: View {
@ObservedObject var item: Items
var body: some View {
NavigationLink(destination: DetailView(item: item)){
VStack(alignment: .leading){
Text(item.name).lineLimit(1)
Text(item.description).lineLimit(1)
}.onAppear {
print("\(self.item.name)")
}
}
}
}