基于 VIewModel 状态更新 SwiftUI 视图?
Updating SwiftUI View Based on VIewModel States?
我在我的 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
}
}
但是,只要这些视图模型属性发生变化,视图就不会像我在 class 中将它们用作 @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 个状态决定属性绑定到视图结果,它们被抽象到视图模型中?
谢谢
将@Published 放在所有 3 个属性之前,如下所示:
@Published var movies: [Movie] = []
@Published var isLoading: Bool = false
@Published var fetchError: String?
通过使 class 符合 ObservableObject,您几乎就成功了,但它本身什么也不做。然后,您需要确保使用我上面显示的 @Published
自动发送更新,或者手动发送 objectWillChange.send()
编辑:
您还应该知道,如果将该数据传递给任何 children,您应该使 parents 属性 成为 @StateObject
并且 children是 ObservedObject
我在我的 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
}
}
但是,只要这些视图模型属性发生变化,视图就不会像我在 class 中将它们用作 @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 个状态决定属性绑定到视图结果,它们被抽象到视图模型中?
谢谢
将@Published 放在所有 3 个属性之前,如下所示:
@Published var movies: [Movie] = []
@Published var isLoading: Bool = false
@Published var fetchError: String?
通过使 class 符合 ObservableObject,您几乎就成功了,但它本身什么也不做。然后,您需要确保使用我上面显示的 @Published
自动发送更新,或者手动发送 objectWillChange.send()
编辑:
您还应该知道,如果将该数据传递给任何 children,您应该使 parents 属性 成为 @StateObject
并且 children是 ObservedObject