我有一个简单的Loader,当其@Publisher设置为true时,它会执行加载动画。发出网络请求时,此发布者在ViewModel上设置为true。我希望此值可以更改我的看法,但事实并非如此。所示的ContentView更为复杂,彼此之间有许多视图,但这是所有视图的根视图。 加载程序是一个Lottie视图,当手动将所有内容设置为true时,该视图都可以完美地工作。加载程序是一个独立的@ObservableObject,我想在其他许多ViewModel中使用它。
为什么从ViewModel进行设置后,我的@ObservedObject var loader
的视图状态没有发生任何变化?
我的装载机:
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)
}
}
}
}
答案 0 :(得分:1)
@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()
,但我希望它在某个地方被激活,因为据我所知,它是激活Loader
的唯一功能。