Ios SwiftUI-在视图模型数组中更新模型时刷新模型视图
问一个简单的问题,但我可能忘记了代码中的某些内容。Ios SwiftUI-在视图模型数组中更新模型时刷新模型视图,ios,swift,mvvm,swiftui,observable,Ios,Swift,Mvvm,Swiftui,Observable,问一个简单的问题,但我可能忘记了代码中的某些内容。 让我们使用图像更好地解释: 我基本上需要在选择/取消选择项目时更新“计数”和“价格” 我的代码结构如下: 型号: class ServiceSelectorModel: Identifiable, ObservableObject { var id = UUID() var serviceName: String var price: Double init(serviceName: String
让我们使用图像更好地解释: 我基本上需要在选择/取消选择项目时更新“计数”和“价格”
我的代码结构如下: 型号:
class ServiceSelectorModel: Identifiable, ObservableObject {
var id = UUID()
var serviceName: String
var price: Double
init(serviceName: String, price: Double) {
self.serviceName = serviceName
self.price = price
}
@Published var selected: Bool = false
}
class ServiceSelectorViewModel: ObservableObject {
@Published var services = [ServiceSelectorModel]()
init() {
self.services = [
ServiceSelectorModel(serviceName: "SERVICE 1", price: 1.80),
ServiceSelectorModel(serviceName: "SERVICE 2", price: 10.22),
ServiceSelectorModel(serviceName: "SERVICE 3", price: 2.55)
]
}
}
视图模型:
class ServiceSelectorModel: Identifiable, ObservableObject {
var id = UUID()
var serviceName: String
var price: Double
init(serviceName: String, price: Double) {
self.serviceName = serviceName
self.price = price
}
@Published var selected: Bool = false
}
class ServiceSelectorViewModel: ObservableObject {
@Published var services = [ServiceSelectorModel]()
init() {
self.services = [
ServiceSelectorModel(serviceName: "SERVICE 1", price: 1.80),
ServiceSelectorModel(serviceName: "SERVICE 2", price: 10.22),
ServiceSelectorModel(serviceName: "SERVICE 3", price: 2.55)
]
}
}
切换视图
struct ServiceToggleView: View {
@ObservedObject var model: ServiceSelectorModel
var body: some View {
VStack(alignment: .center) {
HStack {
Text(model.serviceName)
Toggle(isOn: $model.selected) {
Text(String(format: "€ +%.2f", model.price))
.frame(maxWidth: .infinity, alignment: .trailing)
}
}
.background(model.selected ? Color.yellow : Color.clear)
}
}
}
struct ServiceSelectorView: View {
@ObservedObject var serviceSelectorVM = ServiceSelectorViewModel()
var body: some View {
VStack {
VStack(alignment: .leading) {
ForEach (serviceSelectorVM.services, id: \.id) { service in
ServiceToggleView(model: service)
}
}
let price = serviceSelectorVM.services.filter{ $0.selected }.map{ $0.price }.reduce(0, +)
Text("SELECTED: \(serviceSelectorVM.services.filter{ $0.selected }.count)")
Text(String(format: "TOTAL PRICE: €%.2f", price))
}
}
}
服务选择或查看
struct ServiceToggleView: View {
@ObservedObject var model: ServiceSelectorModel
var body: some View {
VStack(alignment: .center) {
HStack {
Text(model.serviceName)
Toggle(isOn: $model.selected) {
Text(String(format: "€ +%.2f", model.price))
.frame(maxWidth: .infinity, alignment: .trailing)
}
}
.background(model.selected ? Color.yellow : Color.clear)
}
}
}
struct ServiceSelectorView: View {
@ObservedObject var serviceSelectorVM = ServiceSelectorViewModel()
var body: some View {
VStack {
VStack(alignment: .leading) {
ForEach (serviceSelectorVM.services, id: \.id) { service in
ServiceToggleView(model: service)
}
}
let price = serviceSelectorVM.services.filter{ $0.selected }.map{ $0.price }.reduce(0, +)
Text("SELECTED: \(serviceSelectorVM.services.filter{ $0.selected }.count)")
Text(String(format: "TOTAL PRICE: €%.2f", price))
}
}
}
在这段代码中,我能够更新模型的
选中状态
,但视图模型包含所有模型,并且应该刷新价格
而不是更新阵列中的模型似乎没有改变
我忘记了什么?最简单的方法可能是将模型设置为值类型,然后更改其属性。持有它的视图模型将被更新。并更新视图以使用绑定到这些值
struct ServiceSelectorModel: Identifiable {
var id = UUID()
var serviceName: String
var price: Double
init(serviceName: String, price: Double) {
self.serviceName = serviceName
self.price = price
}
var selected: Bool = false
}
struct ServiceToggleView: View {
@Binding var model: ServiceSelectorModel
...
}
...
ForEach (serviceSelectorVM.services.indices, id: \.self) { i in
ServiceToggleView(model: $serviceSelectorVM.services[i])
}
注意:内联编写,未经测试,可能需要修复某些打字错误。如果您仔细注意,您已经创建了两个不同的单一真相来源。这就是父级未更新的原因,因为它未链接到子级 一种方法是将
ServiceSelectorModel
创建为结构,并在子视图中将services
数组作为@Binding
传递。下面是工作示例
视图模型-:
struct ServiceSelectorModel {
var id = UUID().uuidString
var serviceName: String
var price: Double
var isSelected:Bool = false
init(serviceName: String, price: Double) {
self.serviceName = serviceName
self.price = price
}
}
class ServiceSelectorViewModel: ObservableObject,Identifiable {
@Published var services = [ServiceSelectorModel]()
var id = UUID().uuidString
init() {
self.services = [
ServiceSelectorModel(serviceName: "SERVICE 1", price: 1.80),
ServiceSelectorModel(serviceName: "SERVICE 2", price: 10.22),
ServiceSelectorModel(serviceName: "SERVICE 3", price: 2.55)
]
}
}
struct ServiceToggleView: View {
@Binding var model: [ServiceSelectorModel]
var body: some View {
VStack(alignment: .center) {
ForEach(0..<model.count) { index in
HStack{
Text(model[index].serviceName)
Toggle(isOn: $model[index].isSelected) {
Text(String(format: "€ +%.2f", model[index].price))
.frame(maxWidth: .infinity, alignment: .trailing)
}
}.background(model[index].isSelected ? Color.yellow : Color.clear)
}
}
}
}
struct ServiceSelectorView: View {
@ObservedObject var serviceSelectorVM = ServiceSelectorViewModel()
var body: some View {
VStack {
VStack(alignment: .leading) {
ServiceToggleView(model: $serviceSelectorVM.services)
}
let price = serviceSelectorVM.services.filter{ $0.isSelected }.map{ $0.price }.reduce(0, +)
Text("SELECTED: \(serviceSelectorVM.services.filter{ $0.isSelected }.count)")
Text(String(format: "TOTAL PRICE: €%.2f", price))
}
}
}
视图-:
struct ServiceSelectorModel {
var id = UUID().uuidString
var serviceName: String
var price: Double
var isSelected:Bool = false
init(serviceName: String, price: Double) {
self.serviceName = serviceName
self.price = price
}
}
class ServiceSelectorViewModel: ObservableObject,Identifiable {
@Published var services = [ServiceSelectorModel]()
var id = UUID().uuidString
init() {
self.services = [
ServiceSelectorModel(serviceName: "SERVICE 1", price: 1.80),
ServiceSelectorModel(serviceName: "SERVICE 2", price: 10.22),
ServiceSelectorModel(serviceName: "SERVICE 3", price: 2.55)
]
}
}
struct ServiceToggleView: View {
@Binding var model: [ServiceSelectorModel]
var body: some View {
VStack(alignment: .center) {
ForEach(0..<model.count) { index in
HStack{
Text(model[index].serviceName)
Toggle(isOn: $model[index].isSelected) {
Text(String(format: "€ +%.2f", model[index].price))
.frame(maxWidth: .infinity, alignment: .trailing)
}
}.background(model[index].isSelected ? Color.yellow : Color.clear)
}
}
}
}
struct ServiceSelectorView: View {
@ObservedObject var serviceSelectorVM = ServiceSelectorViewModel()
var body: some View {
VStack {
VStack(alignment: .leading) {
ServiceToggleView(model: $serviceSelectorVM.services)
}
let price = serviceSelectorVM.services.filter{ $0.isSelected }.map{ $0.price }.reduce(0, +)
Text("SELECTED: \(serviceSelectorVM.services.filter{ $0.isSelected }.count)")
Text(String(format: "TOTAL PRICE: €%.2f", price))
}
}
}
struct ServiceToggleView:视图{
@绑定变量模型:[ServiceSelectorModel]
var body:一些观点{
VStack(对齐:。中心){
ForEach(0..不要担心打字错误,我只需要一个关于如何修复的建议,而不是复制/粘贴:)