为啥我的@ObservedObject 没有在我的视图中执行更改?
Posted
技术标签:
【中文标题】为啥我的@ObservedObject 没有在我的视图中执行更改?【英文标题】:Why is my @ObservedObject not performing changes in my view?为什么我的@ObservedObject 没有在我的视图中执行更改? 【发布时间】:2020-05-11 14:28:42 【问题描述】:我有一个简单的加载器,当它的 @Publisher 设置为 true 时,它会执行加载动画。发出网络请求时,此发布者在 ViewModel 上设置为 true。我希望这个值能改变我的看法,但事实并非如此。显示的 ContentView 更为复杂,其中包含许多视图,但它是所有视图的根视图。 加载程序是一个 Lottie 视图,当手动将所有内容设置为 true 时,它可以完美运行。 Loader 是一个独立的 @ObservableObject,因为我想在许多其他 ViewModel 中使用它。
为什么我的@ObservedObject var loader
在从 ViewModel 设置时没有对我的视图状态进行任何更改?
我的装载机:
final class Loader: ObservableObject
@Published var isLoading = false
触发加载器的我的视图模型: (在控制台中,loader的值会相应变化)
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)
【问题讨论】:
【参考方案1】:@ObservedObject
是 View 的一个模式,它在外面没有意义,即。在这种情况下在模型中。
这是提供代码的可能解决方案。
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
的函数。
【讨论】:
效果很好,但是只有 OnboardingViewModel 可以触发这个加载器,因为它是这样调用的 InnerView(loader: onboardingViewModel.loader)。但我想使用 Loader: ObservableObject 和许多 ViewModel。以上是关于为啥我的@ObservedObject 没有在我的视图中执行更改?的主要内容,如果未能解决你的问题,请参考以下文章
无法在真实 iPhone 上使用 @ObservedObject
为啥 SwiftUI ObservedObject 不能在列表行中工作?