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

时间:2019-08-15 15:09:56

标签: swiftui

在这种特定情况下,当我尝试更改@EnvironmentObject的{​​{1}}时,我发现该视图并没有立即失效并立即更新。取而代之的是,对变量的更改仅在离开模态并返回后才反映出来。

@Published var

video showing view changing only after modal is dismissed

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

如果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 是Modal中的changeView,则此方法有效。如果它是@State var内的@State varMasterView内的@Binding var,则也可以使用。只是不适用于此设置。

3 个答案:

答案 0 :(得分: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()
        }
    }
}

我测试了一下,它就可以了。

答案 1 :(得分:3)

更改

final class UserData: NSObject, ObservableObject  {

final class UserData: ObservableObject  {

可以解决Xcode11 Beta6中的问题。 SwiftUI似乎无法正确处理实现NSObject的{​​{1}}子类(至少它似乎没有调用它的内部ObservableObject块)。

答案 2 :(得分:1)

在Xcode 11 GM2中,如果您覆盖了objectWillChange,则它需要在已发布变量的setter上调用send()

如果不覆盖objectWillChange,则@EnvironmentObject或@ObservedObject中的已发布变量一旦更改,就应刷新视图。由于在Xcode 11中,GM2 objectWillChange已具有默认实例,因此不再需要在ObservableObject中提供它。