简体   繁体   English

SwiftUI 可观察到 Object 内部环境 Object 不更新视图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM