0

我面临一个问题,即视图不会使用 @Observable 对象自动更新。

struct Person: Identifiable {
  var id: Int
  var name: String

  init(id: Int, name: String){
      self.id = id
      self.name = name
  }

}

class People: ObservableObject {
  @Published var people: [Person]
  @Published var kitchens: [Kitchen]

  init(){
      self.people = [
          Person(id: 1, name:"Javier"),
          Person(id: 2, name:"Juan"),
          Person(id: 3, name:"Pedro")]
 }
}

struct ContentView: View {
@ObservedObject var mypeople: People

var body: some View {
    VStack{
        ForEach(mypeople.people){ person in
            Text("\(person.name)")
        }
        Button(action: {
            self.mypeople.people.append(Person(id: 7, name: "New person"))
        }) {
            Text("Add/Change name")
        }
    }.onAppear {
        self.mypeople.people.append(Person(id: 7, name: "New person"))
    }
}
}

所以,我想做的是我必须在 onAppear 中添加一个新人,而不是在点击按钮时添加一个新人。简而言之,可以说 people 数组已经有三个人,我必须在登陆该视图时添加第四个。

奇怪的是,如果此视图是根视图,则会添加该人,但是,当使用导航链接推送此视图时,它不起作用。在第二种情况下,立即添加和删除一个新人员,使人员数组计数为 3。

但是,只需轻按一下按钮,就可以轻松添加新人。我被困在这里几个小时。任何帮助将不胜感激!提前致谢!

编辑

我调试了更多以找出问题。因此,在 onAppear 中会自动在以下场景中添加新人:

1) 如果 ContentView 是应用程序的根视图。2) 如果 ContentView 是从父视图层次结构中的第一个视图推送的。意思是,如果有 ContentView 的子视图。子视图中的导航链接会产生此问题,但是,直接来自 ContentView 的导航链接会成功添加人员。

为了创建一个navigationLink,我使用了:

NavigationLink(destination:  ContentView()) {
     Text("View All")
}
4

2 回答 2

1

这是否解决了您在评论中提到的场景:

struct TheNavView: View {
@ObservedObject var mypeople: People
@State var newId = Int(arc4random())
var body: some View {
    // the view that create "New person" onAppear
    VStack{
        ForEach(mypeople.people){ person in
            Text("\(person.name)")
        }
        Button(action: {
            self.mypeople.people.append(Person(id: self.newId, name: "New person"))
        }) {
            Text("Add/Change name")
        }
    }.onAppear {
        print("--------> onAppear self.newId: \(self.newId)")
        self.mypeople.people.append(Person(id: self.newId, name: "New person"))
    }
}
}

struct TheSubView: View {
@ObservedObject var mypeople: People
var body: some View {
    // the subView that pushes using NavigationLink
    NavigationView {
        NavigationLink(destination: TheNavView(mypeople: mypeople)) {
            Text("View All")
        }
    }.navigationViewStyle(StackNavigationViewStyle())
}
}

struct ContentView: View {
@ObservedObject var mypeople: People
var body: some View {
    // the ContentView with a subView
    TheSubView(mypeople: mypeople)
}
}
于 2020-04-16T22:53:31.663 回答
0

好的,如果我理解正确,您想在 onAppear 中添加一个新人,而不是在点击按钮时添加一个新人。但是,如果此视图是根视图,则会添加此人,但是,当使用导航链接推送此视图时,它不起作用。

所以我做了一个有效的测试:

struct Person: Identifiable {
var id: Int
var name: String
init(id: Int, name: String){
    self.id = id
    self.name = name
}
}

struct Kitchen: Identifiable {
var id: Int
var name: String
init(id: Int, name: String){
    self.id = id
    self.name = name
}
}

class People: ObservableObject {
@Published var people: [Person]
@Published var kitchens: [Kitchen]
init() {
    self.people = [ Person(id: 1, name:"Javier"),Person(id: 2, name:"Juan"),Person(id: 3, name:"Pedro")]
    self.kitchens = [ Kitchen(id: 1, name:"Kitchen1"),Kitchen(id: 2, name:"Kitchen2"), Kitchen(id: 3, name:"Kitchen3")]
}
}

struct SecondView: View {
@ObservedObject var mypeople: People
@State var newId = Int(arc4random())
var body: some View {
    VStack{
        ForEach(mypeople.people){ person in
            Text("\(person.name)")
        }
        Button(action: {
            self.mypeople.people.append(Person(id: self.newId, name: "New person"))
        }) {
            Text("Add/Change name")
        }
    }.onAppear {
        print("--------> onAppear")
        self.mypeople.people.append(Person(id: self.newId, name: "New person"))
    }
}
}

struct ContentView: View {
@ObservedObject var mypeople: People
var body: some View {
    NavigationView {
        NavigationLink(destination: SecondView(mypeople: mypeople)) {
            Text("View All")
        }
    }.navigationViewStyle(StackNavigationViewStyle())
}
}

当然在 SceneDelegate 中,你必须声明:

var people = People()
window.rootViewController = UIHostingController(rootView: ContentView(mypeople: people))
于 2020-04-16T09:10:24.207 回答