Swiftui 为什么@ObservedObject不在我的视图中执行更改?

Swiftui 为什么@ObservedObject不在我的视图中执行更改?,swiftui,combine,observableobject,Swiftui,Combine,Observableobject,我有一个简单的加载程序,它在@Publisher设置为true时执行加载动画。发出网络请求时,此发布服务器在ViewModel上设置为true。我希望此值可以更改我的视图,但事实并非如此。显示的ContentView更加复杂,其中有许多视图,但它是所有视图的根视图。 加载器是一个Lottie视图,当所有内容都手动设置为true时,它可以完美地工作。加载程序是一个独立的@observeObject,因为我想在许多其他ViewModels中使用它 为什么@ObservedObject var loa

我有一个简单的加载程序,它在@Publisher设置为true时执行加载动画。发出网络请求时,此发布服务器在ViewModel上设置为true。我希望此值可以更改我的视图,但事实并非如此。显示的ContentView更加复杂,其中有许多视图,但它是所有视图的根视图。 加载器是一个Lottie视图,当所有内容都手动设置为true时,它可以完美地工作。加载程序是一个独立的@observeObject,因为我想在许多其他ViewModels中使用它

为什么@ObservedObject var loader在从ViewModel设置时不在我的视图状态中执行任何更改

我的加载器:

final class Loader: ObservableObject {
  @Published var isLoading = false
}
触发加载程序的我的视图模型: 在控制台中,加载程序的值将相应地更改

final class OnboardingViewModel: ObservableObject {

  @ObservedObject var loader = Loader()

  func demoLogin() {
    loaderIsLoading(true)  // loader set to true
    AuthRequest.shared
      .demoLogin()
      .sink(
        receiveCompletion: {
          self.loaderIsLoading(false) }, // loader set to false
        receiveValue: {
          self.enterDemoAction()
          print("Login: \($0.login)\nToken: \($0.token)") })
      .store(in: &subscriptions)
  }

  func loaderIsLoading(_ action: Bool) {
    DispatchQueue.main.async {
      self.loader.isLoading = action
    }
  }
}
这是SwiftUI视图,我希望在其中发生神奇的事情: 子视图和组件之间的关系要复杂得多

struct ContentView: View {

  @EnvironmentObject var onboardingViewModel: OnboardingViewModel

  @ObservedObject var loader = Loader()

  var body: some View {
    ZStack {
    if loader.isLoading {  // this is where it is not updated
      LottieView(named: .loading,
                 loop: loader.isLoading,
                 width: 220, height: 220)
     }
    }
  }
}
@ObservedObject是一种视图模式,它在外部没有意义,即在本例中是在模型中

以下是提供的代码的可能解决方案

模型中的1

final class OnboardingViewModel: ObservableObject {
  var loader = Loader() // << just property

  // ... other code
2鉴于

struct ContentView: View {

  @EnvironmentObject var onboardingViewModel: OnboardingViewModel

  var body: some View {
     InnerView(loader: onboardingViewModel.loader)  // << pass from Env
  }

  struct InnerView: View {
     @ObservedObject var loader: Loader

     var body: some View {
         ZStack {
            if loader.isLoading {  // this is where it is not updated
               LottieView(named: .loading,
                 loop: loader.isLoading,
                 width: 220, height: 220)
            }
         }
     }
  }
}

注意:我看不出您在哪里调用onboardingViewModel.demoLogin,但我希望它是在某个地方激活的,因为在我看来,它是激活加载程序的唯一函数。

它工作正常,但只有onboardingViewModel可以触发此加载程序,因为它以这种方式被称为InnerViewloader:onboardingViewModel.Loader。但是我想将Loader:observateObject与许多ViewModels一起使用。