[英]SwiftUI Observable Object inside Environment Object does not update view
I recently came across an issue where I didn't find a way to work around it.我最近遇到了一个问题,我没有找到解决它的方法。 If I place an observable object inside an environment object, my views don't update when a variable is changing.如果我在 object 环境中放置一个可观察的 object,那么当变量发生变化时,我的视图不会更新。 This is my setup:这是我的设置:
inside SceneDelegate I decalre the parent view with environmentObject:在 SceneDelegate 中,我使用 environmentObject 标记父视图:
let parent = ParentView().environmentObject(Data())
This is the environment Object:这是环境 Object:
class Data: ObservableObject {
enum Page {
case pageOne
}
var page: Page = .pageOne
var person = Person()
}
now all my views are linked to the parent view:现在我的所有视图都链接到父视图:
struct ParentView: View {
@EnvironmentObject var data: Data
var body: some View {
VStack {
if self.data.page == .pageOne {
PageOne()
} else {
Text("No pages")
}
}
}
}
I have a class (I called it "Person"):我有一个 class(我称之为“人”):
import Foundation
import SwiftUI
import Combine
class Person: ObservableObject {
let objectWillChange = PassthroughSubject<Person,Never>()
@Published var age = 30 { didSet { objectWillChange.send(self)} }
func birthday() {
self.age += 1
print(age)
}
}
And this is where my problem occurs:这就是我的问题发生的地方:
struct PageOne: View {
@EnvironmentObject var data: Data
var body: some View {
Text("\(data.person.age)").onTapGesture {
self.data.person.birthday()
}
}
}
When I tap the text, the age of the person is increasing but the view does not update.当我点击文本时,人的年龄在增加,但视图没有更新。 I think I don't even understand why this is happening.我想我什至不明白为什么会这样。 I thought I knew how it works but apparently I don't.我以为我知道它是如何工作的,但显然我不知道。
It looks like in your case Person
doesn't have to be a class .看起来在您的情况下Person
不必是class 。
You can try this instead:你可以试试这个:
class Data: ObservableObject {
enum Page {
case pageOne
}
var page: Page = .pageOne
@Published var person = Person() {
didSet {
objectWillChange.send()
}
}
}
struct Person {
var age = 30
mutating func birthday() {
self.age += 1
print(age)
}
}
If you need Person
to remain a class you can make it @Published
:如果您需要Person
保持 class ,您可以将其@Published
:
class Data: ObservableObject {
enum Page {
case pageOne
}
var page: Page = .pageOne
@Published var person = Person() // <- add `@Published`
}
and remove unnecessary objectWillChange
code from Person
:并从Person
中删除不必要objectWillChange
代码:
class Person: ObservableObject {
@Published var age = 30
func birthday() {
self.age += 1
print(age)
}
}
Then use Person
as an @ObservedObject
in the PageOne
view:然后在PageOne
视图中使用Person
作为@ObservedObject
:
struct ContentView: View {
@EnvironmentObject var data: Data
var body: some View {
VStack {
if self.data.page == .pageOne {
PageOne(person: data.person) // pass `person` object
} else {
Text("No pages")
}
}
}
}
struct PageOne: View {
@ObservedObject var person: Person // observe `person` directly
var body: some View {
Text("\(person.age)").onTapGesture {
self.person.birthday()
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.