更改为@EnvironmentObject中的@Published var不会立即反映出来

Zai*_*ain 4 swiftui

在这种特定情况下,当我尝试更改@EnvironmentObject的时@Published var,我发现该视图并没有立即失效并立即更新。相反,仅在离开模态并返回后,才会反映对变量的更改。

import SwiftUI

final class UserData: NSObject, ObservableObject  {
    @Published var changeView: Bool = false
}

struct MasterView: View {
    @EnvironmentObject var userData: UserData
    @State var showModal: Bool = false

    var body: some View {
        Button(action: { self.showModal.toggle() }) {
            Text("Open Modal")
        }.sheet(isPresented: $showModal, content: {
            Modal(showModal: self.$showModal)
                .environmentObject(self.userData)
        } )
    }
}

struct Modal: View {
    @EnvironmentObject var userData: UserData
    @Binding var showModal: Bool

    var body: some View {
        VStack {
            if userData.changeView {
                Text("The view has changed")
            } else {
                Button(action: { self.userData.changeView.toggle() }) {
                    Text("Change View")
                }
            }
        }
    }
}



#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        MasterView().environmentObject(UserData())
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

该视频显示了视图仅在消除模态后才发生变化

这是一个错误还是我做错了什么?

如果changeView@State var内部模式,则此方法有效。它也可以,如果它是一个@State varMasterView有一个@Binding varModal。它不适用于此设置。

dfd*_*dfd 6

有几件事。

  • 如果将“按钮”移动MasterView到任一位置,则设置将不起作用。
  • import Combine的代码中没有(不要担心,仅此一项是没有帮助的)。

解决方法是这里。我不知道这是一个错误,还是文档不完善-IIRC声明它objectWillChange是隐式的。

在添加import Combine代码的同时,将其更改UserData为:

final class UserData: NSObject, ObservableObject  {
    var objectWillChange = PassthroughSubject<Void, Never>()
    @Published var changeView: Bool = false {
        willSet {
            objectWillChange.send()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我测试了东西,它起作用了。


Fab*_*ian 4

改变

final class UserData: NSObject, ObservableObject  {
Run Code Online (Sandbox Code Playgroud)

final class UserData: ObservableObject  {
Run Code Online (Sandbox Code Playgroud)

确实修复了 Xcode11 Beta6 中的问题。SwiftUI 似乎确实无法正确处理NSObject子类的实现(至少它看起来ObservableObject不会调用它的内部块)。willSet