Data binding 父导航视图的SwiftUI更新数据

Data binding 父导航视图的SwiftUI更新数据,data-binding,swiftui,navigationlink,Data Binding,Swiftui,Navigationlink,如何更新位于NavigationView详细信息中的TextField中的数据?我希望在父视图的列表中更新数据。这是我的密码: class Address: ObservableObject, Identifiable { let id = UUID() @Published var name: String @Published var age: String init(name: String, age: String) { self

如何更新位于NavigationView详细信息中的TextField中的数据?我希望在父视图的列表中更新数据。这是我的密码:

class Address: ObservableObject, Identifiable {
    let id = UUID()
    @Published var name: String
    @Published var age: String
    
    init(name: String, age: String) {
        self.name = name
        self.age = age
    }
}
class AddressBook: ObservableObject {
    @Published var addresses: [Address]

    init(addresses: [Address]) {
        self.addresses = addresses
    }
}
struct TestData {
    static let addressbook = AddressBook(addresses: [
        Address(name: "Person1", age: "39"),
        Address(name: "Person2", age: "22")
    ])
}
struct ContentView: View {
    @ObservedObject var addressbook = TestData.addressbook
    
    var body: some View {
        NavigationView {
            List (addressbook.addresses) {address in
                NavigationLink(destination: AddressDetail(address: address)) {
                    Text(address.name)
                }
            }
            .navigationBarTitle("Addressbook")
        }
        
    }
}

struct AddressDetail: View {
    @ObservedObject var address: Address
    
    var body: some View {
        Form {
            TextField("name", text: $address.name)
            
            TextField("age", text: $address.age)
        }
        
    }
}
这段代码不起作用:如果我转到AddressDetail视图,更改TextField值,然后返回,更改不会在列表视图中更新


Nico

问题在于
地址
是一个类,因此如果其发布的属性发生了更改,则
地址
中的引用不会更改,而是
内容视图
视图将
地址簿
作为地址容器进行观察

这里是可能的方法的演示(在Xcode 12b/iOS 14上测试并工作,也在11.4/iOS 13.4上)

替代:基于
绑定
(需要更多的更改,因此,对我来说,不太可取,但值得一提

struct Address: Identifiable, Hashable {
    let id = UUID()
    var name: String
    var age: String

    init(name: String, age: String) {
        self.name = name
        self.age = age
    }
}
class AddressBook: ObservableObject {
    @Published var addresses: [Address]

    init(addresses: [Address]) {
        self.addresses = addresses
    }
}
struct TestData {
    static let addressbook = AddressBook(addresses: [
        Address(name: "Person1", age: "39"),
        Address(name: "Person2", age: "22")
    ])
}

struct ContentView: View {
    @ObservedObject var addressbook = TestData.addressbook

    var body: some View {
        NavigationView {
            List (Array(addressbook.addresses.enumerated()), id: \.element) { i, address in
                NavigationLink(destination: AddressDetail(address: self.$addressbook.addresses[i])) {
                    Text(address.name)
                }
            }
            .navigationBarTitle("Addressbook")
        }

    }
}

struct AddressDetail: View {
    @Binding var address: Address

    @State private var name: String
    @State private var age: String

    init(address: Binding<Address>) {
        _address = address
        _name = State(initialValue: _address.wrappedValue.name)
        _age = State(initialValue: _address.wrappedValue.age)
    }
    var body: some View {
        Form {
            TextField("name", text: $name)

            TextField("age", text: $age)
        }
        .onDisappear {
            self.address.name = self.name
            self.address.age = self.age
        }
    }
}
结构地址:可识别、可散列{ 设id=UUID() 变量名称:String 变量年龄:字符串 init(名称:String,年龄:String){ self.name=名称 self.age=年龄 } } 类地址簿:ObservieObject{ @已发布的var地址:[地址] 初始化(地址:[地址]){ self.addresses=地址 } } 结构测试数据{ 静态let addressbook=地址簿(地址:[ 地址(姓名:“Person1”,年龄:“39”), 地址(姓名:“Person2”,年龄:“22”) ]) } 结构ContentView:View{ @ObservedObject var addressbook=TestData.addressbook var body:一些观点{ 导航视图{ 列表(数组(addressbook.addresses.enumerated()),id:\.element){i,中的地址 NavigationLink(目的地:AddressDetail(地址:self.$addressbook.addresses[i])){ 文本(地址、名称) } } .navigationBarTitle(“地址簿”) } } } 结构AddressDetail:视图{ @绑定变量地址:地址 @国家私有变量名称:String @国家私有变量年龄:字符串 init(地址:Binding){ _地址 _名称=状态(初始值:_address.wrappedValue.name) _年龄=状态(初始值:_address.wrappedValue.age) } var body:一些观点{ 形式{ TextField(“名称”,text:$name) 文本字段(“年龄”,文本:$age) } 翁迪萨佩尔先生{ self.address.name=self.name self.address.age=self.age } } }
谢谢,它很有效!但是这个问题没有其他解决方案吗?在我看来,导航视图中列表后面的编辑表单非常常用。我想将address参数作为$address之类的内容传递,但在闭包中似乎不起作用。您如何使用@environmentObject?@Nico,
@EnvironmentObject
的行为与
@ObservedObject
相同,因此原始问题仍然如第一段所述。另一种方法是使用
@Binding
-请参阅更新的用法。
struct Address: Identifiable, Hashable {
    let id = UUID()
    var name: String
    var age: String

    init(name: String, age: String) {
        self.name = name
        self.age = age
    }
}
class AddressBook: ObservableObject {
    @Published var addresses: [Address]

    init(addresses: [Address]) {
        self.addresses = addresses
    }
}
struct TestData {
    static let addressbook = AddressBook(addresses: [
        Address(name: "Person1", age: "39"),
        Address(name: "Person2", age: "22")
    ])
}

struct ContentView: View {
    @ObservedObject var addressbook = TestData.addressbook

    var body: some View {
        NavigationView {
            List (Array(addressbook.addresses.enumerated()), id: \.element) { i, address in
                NavigationLink(destination: AddressDetail(address: self.$addressbook.addresses[i])) {
                    Text(address.name)
                }
            }
            .navigationBarTitle("Addressbook")
        }

    }
}

struct AddressDetail: View {
    @Binding var address: Address

    @State private var name: String
    @State private var age: String

    init(address: Binding<Address>) {
        _address = address
        _name = State(initialValue: _address.wrappedValue.name)
        _age = State(initialValue: _address.wrappedValue.age)
    }
    var body: some View {
        Form {
            TextField("name", text: $name)

            TextField("age", text: $age)
        }
        .onDisappear {
            self.address.name = self.name
            self.address.age = self.age
        }
    }
}