我最近开始使用SwiftUI-MVVM,我不确定我在MVVM中做事的方式。我在ViewModel@Published var list: [Product]
中通过此属性显示产品列表,并且一次只能选择一个产品,因此我在ViewModel中创建了@Published
属性作为@Published var selectedProduct: Product
。现在我将ProductRow视图中的数据传递为
ForEach(viewModel.list) product in {
ProductRow(product, selectedProduct: $viewModel.selectedProduct)
.tapGesture {
viewModel.selectedProduct = product
}
}
在ProductRow
视图中,我正在更改所选产品的颜色。
所以我想知道我是否在使用MVVM来实现这个功能的正确路径上,或者在MVVM中有其他最好的方法来实现这些逻辑。
我想保持ViewModel内的所有逻辑,所以我没有为selectedProduct创建任何@State
属性。
这是一个可能的改进。它没有使用视图修饰符,因为我只改变了背景色
import SwiftUI
import PlaygroundSupport
struct ProductPage: View {
class ViewModel: ObservableObject {
var products: [Product] = [Product(name: "Milk"), Product(name: "Candy"), Product(name: "Carrot")]
@Published var selectedProduct: Product?
}
@StateObject var viewModel: ViewModel = ViewModel()
var body: some View {
HStack {
ForEach(viewModel.products) { product in
ProductRow(product: product, foregroundColor: getForegroundColor(for: product))
.onTapGesture {
viewModel.selectedProduct = product
}
}
}
}
func getForegroundColor(for product: Product) -> Color {
(product == viewModel.selectedProduct) ? .red : .black
}
}
struct Product: Identifiable, Equatable {
var name: String
var id: String { name }
}
struct ProductRow: View {
var product: Product
var foregroundColor: Color
var body: some View {
Text(product.name)
.foregroundColor(foregroundColor)
}
}
PlaygroundPage.current.setLiveView(
ProductPage()
)