@Publisher が true に設定されている場合に読み込みアニメーションを実行する単純な Loader があります。このパブリッシャーは、ネットワーク リクエストを行うときに ViewModel で true に設定されます。この値でビューを変更したいのですが、そうではありません。示されている ContentView は、相互に多くのビューが含まれているより複雑ですが、それらすべてのルート ビューです。そしてローダーは、すべてが手動で true に設定されている場合に完全に機能する Lottie ビューです。Loader は、他の多くの ViewModel で使用したいので、スタンドアロンの @ObservableObject です。
@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)
}
}
}
}