基于 VIewModel 状态更新 SwiftUI 视图?
Posted
技术标签:
【中文标题】基于 VIewModel 状态更新 SwiftUI 视图?【英文标题】:Updating SwiftUI View Based on VIewModel States? 【发布时间】:2021-03-13 11:30:40 【问题描述】:我在我的 SwiftUI 视图中使用 @State
进行了设置,并在视图中进行了我的所有操作(加载 API 等),但是当我尝试重组它而不使用 @ViewBuilder
和 @State
并使用 @ObservedObject
ViewModel,我失去了根据 @State
变量动态更改视图的能力
我的代码现在是
@ObservedObject private var contentViewModel: ContentViewModel
init(viewModel: ContentViewModel)
self.contentViewModel = viewModel
var body: some View
if contentViewModel.isLoading
loadingView
else if contentViewModel.fetchError != nil
errorView
else if contentViewModel.movies.isEmpty
emptyListView
else
moviesList
但是,每当这些视图模型属性发生变化时,视图不会像我在类中将它们用作 @State
属性时那样更新...
ViewModel如下:
final class ContentViewModel: ObservableObject
var movies: [Movie] = []
var isLoading: Bool = false
var fetchError: String?
private let dataLoader: DataLoaderProtocol
init(dataLoader: DataLoaderProtocol = DataLoader())
self.dataLoader = dataLoader
fetch()
func fetch()
isLoading = true
dataLoader.loadMovies [weak self] result, error in
guard let self = `self` else return
self.isLoading = false
guard let result = result else
return print("api error fetching")
guard let error = result.errorMessage, error != "" else
return self.movies = result.items
return self.fetchError = error
现在我如何将这 3 个状态决定属性绑定到视图结果,现在它们被抽象到视图模型中?
谢谢
【问题讨论】:
【参考方案1】:将@Published 放置在您的所有 3 个属性之前,如下所示:
@Published var movies: [Movie] = []
@Published var isLoading: Bool = false
@Published var fetchError: String?
通过使类符合 ObservableObject,您几乎可以做到这一点,但它本身什么也不做。然后,您需要确保使用上面显示的@Published
自动发送更新或手动发送objectWillChange.send()
编辑:
您还应该知道,如果您将该数据传递给任何孩子,您应该将父母的财产设为@StateObject
,而孩子的财产设为ObservedObject
【讨论】:
啊,太近了!谢谢,有关如何处理此“不允许从后台线程发布更改的任何建议;确保在模型更新时从主线程(通过接收(on :) 等运算符)发布值。”错误我没有被抛出? 是的,为避免此错误,请确保在更新值时位于主线程上。因此,无论您遇到该错误,都将该行代码包装在 `DispatchQueue.main.async //error代码 在这种情况下,我会说它在你的 fetch() 方法中的某个地方以上是关于基于 VIewModel 状态更新 SwiftUI 视图?的主要内容,如果未能解决你的问题,请参考以下文章
为啥将 ViewModel 添加到我的 SwiftUI 应用程序后我的 UI 没有更新?
在父 swiftui 视图中,我如何知道内部视图 viewmodel void 方法中的状态何时发生变化?
SwiftUI 从 ViewModel 预填充 TextField
SwiftUI:ObservableObject 在重绘时不会保持其状态