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