我目前正在学习SwiftUI,并试图理解@EnvironmentObject
,这让我觉得有点困惑。
我想在我的应用程序中共享一个包含一些数据的商店,所以我写了这样的文章:
class Store: ObservableObject {
@Published var user: User?
}
class User: ObservableObject {
@Published var name: String?
}
我的应用程序视图:
struct AppView: View {
@EnvironmentObject var store: Store
var body: some View {
ContentView()
.environmentObject(store)
}
}
}
场景电报:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var store = Store()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let appView = AppView().environmentObject(store)
window.rootViewController = UIHostingController(rootView: appView)
self.window = window
window.makeKeyAndVisible()
}
}
}
并且在ContentView
:中
struct ContentView: View {
@EnvironmentObject var store: Store
var body: some View {
VStack {
TextField("Type some text here", text: $store.user?.name ?? "")
}
}
}
然而,我在声明TextField
:的行上遇到了一个错误
可选类型"Binding?"的值必须展开为"Binding"类型的值
我不明白这意味着什么,也不知道在这里该怎么办。
感谢您的帮助
如果user
和name
变量都可以是nil
,那么这里有一个可能的解决方案-您需要使用自定义绑定:
struct ContentView: View {
@EnvironmentObject var store: Store
var binding: Binding<String> {
.init(get: {
store.user?.name ?? ""
}, set: {
store.user?.name = $0
})
}
var body: some View {
VStack {
TextField("Type some text here", text: binding)
}
}
}
但是,您应该考虑仅当存在user
变量时才显示此TextField
。否则,你真正在编辑什么?如果用户丢失,则不能是该用户的名称。。。
或者,尝试使这两个变量都不是可选的(最好将User
更改为结构(:
class Store: ObservableObject {
@Published var user = User(name: "test") // init here or in the `init`
}
struct User {
var name: String // assuming that a `User` always has a `name`
}
CCD_ 10将正常工作:
TextField("Type some text here", text: $store.user.name)