[英]Confusing about @EnvironmentObject in SwiftUI
我正在尝试在 SwiftUI 中练习@EnvironmentObject
工具。
在ContentView
中共享 object User
初始化。
当我从 ContentView 切换到 NameView 时工作得很好。
但是,从 NameView 到 AgeView 失败了。 (请查看错误消息和代码 session)
错误信息
Fatal error: No ObservableObject of type User found.
有人可以给我建议吗? 我错过了什么吗? 谢谢
代码
init "User" type in contentView
NavigationView
+-----------+ +--------+ +-------+
|ContentView+--NavigationLink-->|NameView+--NavigationLink-->|AgeView|
+-----------+ +--------+ +-------+
final class User: ObservableObject {
@Published var name: String
@Published var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
struct ContentView: View {
var user: User = User(name: "SomeName", age: 44)
var body: some View {
NavigationView {
VStack {
Text("name: \(self.user.name) age: \(self.user.age)")
NavigationLink(destination: NameView().environmentObject(self.user)) {
Text("Show Name")
}
}
}
}
}
struct NameView: View {
@EnvironmentObject var user: User
var body: some View {
VStack {
Text("name: \(self.user.name)")
NavigationLink(destination: AgeView()) {
Text("Show Age")
}
}
}
}
struct AgeView: View {
@EnvironmentObject var user: User
var body: some View {
VStack {
Text("age: \(self.user.age)")
}
}
}
希望这可以帮助您了解以下示例:
我们有我们的model ,它是可观察的,并且所有变量都已发布:
class A: ObservableObject {
@Published var id: String = ""
@Published var value: String = ""
}
将其用作EnvironmentObject时,请确保在SceneDelegate.swift中进行如下设置:
let example = Example()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: example.environmentObject(A()))
self.window = window
window.makeKeyAndVisible()
}
然后我们可以在所有视图中使用这个EnvironmentObject :
struct Example: View {
@EnvironmentObject var obj: A
var body: some View {
Button(action: {
self.obj.value = "Hi im changed"
}) {
Text("Change me")
}
}
}
有时,当您想更新此 object 中的数据时,xCode 可能会给您一个关于“没有为...类名等设置环境对象”的错误。 ,在这种情况下,您需要将 EnvironmentObject 传递给目标视图:
DestinationView().environmentObject(self.A)
希望这有帮助,祝你好运!
您正在将 SceneDelegate 中的 EnvironmentObject 分配给 ContentView,因此 ContentView 的所有子视图都可以自动访问您的用户。
因此,不需要像这里一样再次传递它: NameView().environmentObject(self.user)
如果您在 a.sheet 修饰符中显示 View ,则只需要再次传递 environmentObject ,因为它基本上是一个新的独立视图。
final class User: ObservableObject {
@Published var name: String
@Published var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
struct ContentView: View {
@EnvironmentObject var user: User
var body: some View {
NavigationView {
VStack {
Text("name: \(self.user.name) age: \(self.user.age)")
NavigationLink(destination: NameView()) {
Text("Show Name")
}
}
}
}
}
struct NameView: View {
@EnvironmentObject var user: User
var body: some View {
VStack {
Text("name: \(self.user.name)")
NavigationLink(destination: AgeView()) {
Text("Show Age")
}
}
}
}
struct AgeView: View {
@EnvironmentObject var user: User
var body: some View {
VStack {
Text("age: \(self.user.age)")
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.