Swiftui @已发布的不使用类型数组,但可以使用单个类型

Swiftui @已发布的不使用类型数组,但可以使用单个类型,swiftui,swiftui-navigationlink,observableobject,Swiftui,Swiftui Navigationlink,Observableobject,我正在测试非常简单的代码,有一个类符合@observateObject协议,还有两个@Published属性,一个接受我自定义类型对象的数组,另一个只是同一类的普通类型。我有两种观点,其中父母持有单一的真理来源,它有一个列表和一个导航链接。NavigationLink正在将@已发布的数组对象作为绑定传递到子视图 问题-: import SwiftUI struct Person: Identifiable { let id: String = UUID().uuidString

我正在测试非常简单的代码,有一个类符合
@observateObject
协议,还有两个
@Published
属性,一个接受我自定义
类型
对象的数组,另一个只是同一类的普通
类型
。我有两种观点,其中父母持有单一的真理来源,它有一个
列表和一个
导航链接。NavigationLink正在将
@已发布的
数组对象作为
绑定
传递到子视图

问题-:

import SwiftUI


struct Person: Identifiable {
    let id: String = UUID().uuidString
    var name: String = "Tushar"
    var age: Int = 25
    
    init(name: String,age: Int) {
        self.name = name
        self.age = age
    }
}

 class PersonStore: ObservableObject {
    @Published var name: [Person] = [Person(name:"foo",age:23),Person(name:"foobar",age:23)]
    //@Published var name: Person = Person(name:"foo",age:23)
}

struct ContentViewsss: View {
    
    @ObservedObject var store = PersonStore()
    
    @State var isEditing = false
    
    var body: some View {
        NavigationView{
            List(store.name.indices){ index in
                NavigationLink(destination: ContentViewsss1(store: $store.name[index])) {
                    Text("Edit")
                }
            }.navigationTitle(“Welcome")
        }
    }
}

struct ContentViewsss1: View {
    
    @Binding var store: Person

    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
    }
}
import SwiftUI


struct Person: Identifiable {
    let id: String = UUID().uuidString
    var name: String = "Tushar"
    var age: Int = 25
    
    init(name: String,age: Int) {
        self.name = name
        self.age = age
    }
}

 class PersonStore: ObservableObject {
   // @Published var name: [Person] = [Person(name:"foo",age:23),Person(name:"foobar",age:23)]
    @Published var name: Person = Person(name:"foo",age:23)
}

struct ContentViewsss: View {
    
    @ObservedObject var store = PersonStore()
    
    @State var isEditing = false
    
    var body: some View {
        NavigationView{
            List{ 
                NavigationLink(destination: ContentViewsss1(store: $store.name)) {
                    Text("Edit")
                }
            }.navigationTitle("Welcome")
        }
    }
}

struct ContentViewsss1: View {
    
    @Binding var store: Person

    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
    }
}
当我在
TextField
中键入时,视图没有更新。它正在修改
@Published
对象属性,但不更新子视图。这只发生在我测试对象的
数组
时,但是现在如果我注释对象的
数组
属性并简单地使用另一个属性(不带数组),它就可以更新了

谁能解释一下背后的原因,这是一个错误吗?或者
Array
在幕后做其他事情

不起作用示例-:

import SwiftUI


struct Person: Identifiable {
    let id: String = UUID().uuidString
    var name: String = "Tushar"
    var age: Int = 25
    
    init(name: String,age: Int) {
        self.name = name
        self.age = age
    }
}

 class PersonStore: ObservableObject {
    @Published var name: [Person] = [Person(name:"foo",age:23),Person(name:"foobar",age:23)]
    //@Published var name: Person = Person(name:"foo",age:23)
}

struct ContentViewsss: View {
    
    @ObservedObject var store = PersonStore()
    
    @State var isEditing = false
    
    var body: some View {
        NavigationView{
            List(store.name.indices){ index in
                NavigationLink(destination: ContentViewsss1(store: $store.name[index])) {
                    Text("Edit")
                }
            }.navigationTitle(“Welcome")
        }
    }
}

struct ContentViewsss1: View {
    
    @Binding var store: Person

    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
    }
}
import SwiftUI


struct Person: Identifiable {
    let id: String = UUID().uuidString
    var name: String = "Tushar"
    var age: Int = 25
    
    init(name: String,age: Int) {
        self.name = name
        self.age = age
    }
}

 class PersonStore: ObservableObject {
   // @Published var name: [Person] = [Person(name:"foo",age:23),Person(name:"foobar",age:23)]
    @Published var name: Person = Person(name:"foo",age:23)
}

struct ContentViewsss: View {
    
    @ObservedObject var store = PersonStore()
    
    @State var isEditing = false
    
    var body: some View {
        NavigationView{
            List{ 
                NavigationLink(destination: ContentViewsss1(store: $store.name)) {
                    Text("Edit")
                }
            }.navigationTitle("Welcome")
        }
    }
}

struct ContentViewsss1: View {
    
    @Binding var store: Person

    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
    }
}
工作示例-:

import SwiftUI


struct Person: Identifiable {
    let id: String = UUID().uuidString
    var name: String = "Tushar"
    var age: Int = 25
    
    init(name: String,age: Int) {
        self.name = name
        self.age = age
    }
}

 class PersonStore: ObservableObject {
    @Published var name: [Person] = [Person(name:"foo",age:23),Person(name:"foobar",age:23)]
    //@Published var name: Person = Person(name:"foo",age:23)
}

struct ContentViewsss: View {
    
    @ObservedObject var store = PersonStore()
    
    @State var isEditing = false
    
    var body: some View {
        NavigationView{
            List(store.name.indices){ index in
                NavigationLink(destination: ContentViewsss1(store: $store.name[index])) {
                    Text("Edit")
                }
            }.navigationTitle(“Welcome")
        }
    }
}

struct ContentViewsss1: View {
    
    @Binding var store: Person

    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
    }
}
import SwiftUI


struct Person: Identifiable {
    let id: String = UUID().uuidString
    var name: String = "Tushar"
    var age: Int = 25
    
    init(name: String,age: Int) {
        self.name = name
        self.age = age
    }
}

 class PersonStore: ObservableObject {
   // @Published var name: [Person] = [Person(name:"foo",age:23),Person(name:"foobar",age:23)]
    @Published var name: Person = Person(name:"foo",age:23)
}

struct ContentViewsss: View {
    
    @ObservedObject var store = PersonStore()
    
    @State var isEditing = false
    
    var body: some View {
        NavigationView{
            List{ 
                NavigationLink(destination: ContentViewsss1(store: $store.name)) {
                    Text("Edit")
                }
            }.navigationTitle("Welcome")
        }
    }
}

struct ContentViewsss1: View {
    
    @Binding var store: Person

    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
    }
}

比如说,引起问题的不是数组,而是
列表。您将看到,在原始代码中,如果将
列表更改为
ForEach
,它将正常工作。我不确定崩溃发生在哪里,甚至比人们想象的还要微妙

我的建议是使用中间视图模型。以下代码起作用:

class ViewModel: ObservableObject {
    @Published var person : Person {
        didSet {
            binding.wrappedValue = person
        }
    }
    var binding : Binding<Person>
    
    init(withPersonBinding person: Binding<Person>) {
        self.person = person.wrappedValue
        self.binding = person
    }
}

struct ContentViewsss1: View {
    //@Binding var store: Person
    @ObservedObject var store : ViewModel
    
    var body: some View {
        TextField("My Text", text: $store.person.name)
        Text(store.person.name)
    }
}
现在,这里是真正奇怪的一点。如果返回原始代码并将详细视图修改为:

struct ContentViewsss1: View {
    
    @Binding var store: Person
    @State private var txt = ""
    
    var body: some View {
        TextField("My Text", text: $store.name)
        Text(store.name)
        TextField("Other text", text: $txt)
    }
}

您将看到,如果编辑第一个文本字段,您所做的更改将不会反映出来(正如您所经历的那样)但是,一旦您更改第二个字段中的文本,@State中的更改将触发它同时检查@Binding,并且该字段将被更新。这同样只发生在
List
上,而不是
ForEach
上。SwiftUI的奥秘…

我想当我将每个都放在列表中时,我也遇到了它,然后它也不起作用了。这真是迅捷的奥秘。但是,感谢您对解决方案的建议。在我的测试列表中,{ForEach{}}展示了这种行为,但ForEach本身并没有