SwiftUI:在视图之间传递 ObservableObject 时,表达式类型在没有更多上下文的情况下不明确

SwiftUI: Type of expression is ambiguous without more context, When passing ObservableObject between Views

我在 SwiftUI 中寻找 DataStore 的示例并找到了这个示例。

import SwiftUI
import Combine

class MyDatabase: ObservableObject {
    let didChange = PassthroughSubject<MyDatabase, Never>()

    var contacts: [Contact] = [
        Contact(id: 1, name: "Anna"), Contact(id: 2, name: "Beto"),
        Contact(id: 3, name: "Jack"), Contact(id: 4, name: "Sam")
    ] {
        didSet {
            didChange.send(self)
        }
    }

    struct Contact: Identifiable{
        var id: Int
        var name: String
    }
}

struct ContactsList: View {
    @EnvironmentObject private var database: MyDatabase

    var body: some View {
        NavigationView {
            List($database.contacts) { contact in
                NavigationLink(destination: ContactDetail(contact: contact)) {
                    Text(verbatim: contact.value.name)
                    //here Error 1: Types of expression....
                }
            }
            .navigationBarTitle(Text("Contacts"))
        }
    }
}

struct ContactDetail: View {
    @Binding var contact: MyDatabase.Contact

    var body: some View {
        VStack {
            TextField($contact[\.name])
                .textFieldStyle(.roundedBorder)
                .font(.title)
                .padding()
            //here Error 2: Types of expression....
            Spacer()
        }
        .navigationBarTitle(Text("Edit"), displayMode: .inline)
    }
}

但是,在测试之后,我多次出现以下错误:

Type of expression is ambiguous without more context

我也尝试按照相同的解决方案遵循教程https://mecid.github.io/2019/07/03/managing-data-flow-in-swiftui/ 但我得到了同样的错误。 最新测试版中的绑定有什么变化吗? 我 运行 测试版 6

您似乎在像 BindableObject 一样使用 ObservableObjectBindableObject 被替换自 beta 4 (?)。

BindableObject is replaced by the ObservableObject protocol from the Combine framework.

didChange 更改为 objectWillChange,他应该在 willChange 观察者中被调用。

为了避免重复自己,@Published 属性为您合成了 willChange

You can manually conform to ObservableObject by defining an objectWillChange publisher that emits before the object changes. However, by default, ObservableObject automatically synthesizes objectWillChange and emits before any @Published properties change.

class User: ObservableObject {

    @Published var name: String = ""
    @Published var email: String = ""

}

如果您想要绑定 ObservableObject:

,请使用 @ObservedObject
struct MyView: View {

    @ObservedObject var user: User = User()

    var body: some View {
        TextField("Name", text: $user.name)
    }

}

如果您因为使用 @EnvironmentObject 而仍然遇到问题,请尝试查看: