Swiftui:是否可以将观察者视为环境对象?
如果我使用@publed
属性创建一个observableObject
,并将其注入Swifui视图中,则使用.environMentObject()
,该视图响应于变化可观察的对象如预期的。
class CounterStore: ObservableObject {
@Published private(set) var counter = 0
func increment() {
counter += 1
}
}
struct ContentView: View {
@EnvironmentObject var store: CounterStore
var body: some View {
VStack {
Text("Count: \(store.counter)")
Button(action: { store.increment() }) {
Text("Increment")
}
}
}
}
点击“增量”将增加计数。
但是,如果我不使用EnvironmentObject
,而是将商店实例传递到视图中,则编译器不抱怨,商店方法engrement()
在按钮被轻拍,但view
中的计数不是更新。
struct ContentViewWithStoreAsParameter: View {
var store: CounterStore
var body: some View {
VStack {
Text("Count: \(store.counter) (DOES NOT UPDATE)")
Button(action: { store.increment() }) {
Text("Increment")
}
}
}
}
这是我调用这两种视图的方式:
@main
struct testApp: App {
var store = CounterStore()
var body: some Scene {
WindowGroup {
VStack {
ContentView().environmentObject(store) // works
ContentViewWithStoreAsParameter(store: store) // broken
}
}
}
}
有没有办法将observableObject
作为参数作为参数? (或什么魔术是.environmentalObject()
在幕后做什么?
If I create an ObservableObject
with a @Published
property and inject it into a SwifUI view with .environmentObject()
, the view responds to changes in the ObservableObject as expected.
class CounterStore: ObservableObject {
@Published private(set) var counter = 0
func increment() {
counter += 1
}
}
struct ContentView: View {
@EnvironmentObject var store: CounterStore
var body: some View {
VStack {
Text("Count: \(store.counter)")
Button(action: { store.increment() }) {
Text("Increment")
}
}
}
}
Tapping on "Increment" will increase the count.
However, if I don't use the EnvironmentObject
and instead pass the store instance into the view, the compiler does not complain, the store method increment()
is called when the button is tapped, but the count in the View
does not update.
struct ContentViewWithStoreAsParameter: View {
var store: CounterStore
var body: some View {
VStack {
Text("Count: \(store.counter) (DOES NOT UPDATE)")
Button(action: { store.increment() }) {
Text("Increment")
}
}
}
}
Here's how I'm calling both Views:
@main
struct testApp: App {
var store = CounterStore()
var body: some Scene {
WindowGroup {
VStack {
ContentView().environmentObject(store) // works
ContentViewWithStoreAsParameter(store: store) // broken
}
}
}
}
Is there a way to pass an ObservableObject
into a View as a parameter? (Or what magic is .environmentalObject()
doing behind the scenes?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
应该以某种方式观察到
It should be observed somehow, so next works
您可以轻松地以
@StateObject
>:但是,商店通常仅适用于需要它的视图,为什么此解决方案在此上下文中最有意义:
You can pass down your store easily as
@StateObject
:However, the store should normally only be available for the views that need it, why this solution would make the most sense in this context: