I have a simple Loader that performs a loading animation when its @Publisher is set to true. This publisher is set to true on a ViewModel when making a network request. I would like this value to change my view, which it doesn't. The ContentView shown is more complex with many views inside each other, but it is the root view of them all. And the loader is a Lottie view that works perfectly when everything is set to true manually. The Loader is a stand-alone @ObservableObject as I want to use it in many others ViewModels.
Why is my @ObservedObject var loader
not performing any change in my view state when set from a ViewModel?
My loader:
final class Loader: ObservableObject {
@Published var isLoading = false
}
My view model which trigger the loader: (In the console, the values of the loader are changing accordingly)
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
}
}
}
This is the SwiftUI view where I want the magic happens: (It is much more complicated than this with subviews and components inside each other)
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)
}
}
}
}