SwiftUI:可选类型'Binding<String>?'的值必须解包为类型 'Binding<String>' 的值



我目前正在学习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"类型的值

我不明白这意味着什么,也不知道在这里该怎么办。

感谢您的帮助

如果username变量都可以是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)

最新更新