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
一样使用 ObservableObject
。 BindableObject
被替换自 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
而仍然遇到问题,请尝试查看:
我在 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
一样使用 ObservableObject
。 BindableObject
被替换自 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
而仍然遇到问题,请尝试查看: