SwiftUI如何通过单个删除按钮同步扣减不同变量的总值
问题原因
当前实现无法在删除任务时同步扣减分项负载,核心问题有三点:
Task数据模型仅存储了总金额amount字段,没有为每条任务保存对应的load1、load2分项数值,删除操作时没有可用于扣减的分项数据源- 添加逻辑被拆分在两个独立按钮中,统计值累加、任务存储两个动作不同步,容易出现数据不一致
- 删除逻辑仅处理了总金额
gp的扣减,未覆盖loadA、loadB两个分项统计值,且原有逻辑仅取第一个待删除索引处理,批量删除时会出现统计错误
修复步骤
- 扩展
Task模型,新增load1、load2存储属性,让每个任务条目独立持有自己对应的两个分项负载值 - 合并添加操作逻辑,点击添加按钮时同步完成总金额计算、三类统计值累加、任务入库三个动作,移除冗余的空白按钮
- 重写删除方法,遍历所有待删除的索引位置,逐个扣减对应任务的总金额、分项负载值到全局统计变量,最后再移除任务条目,同时兼容单条、批量删除场景
修改后可运行代码
import SwiftUI struct Task: Identifiable { var id: UUID var toDoItem: String var amount: Float var load1: Float var load2: Float init(toDoItem: String, amount: Float, load1: Float, load2: Float) { self.id = UUID() self.toDoItem = toDoItem self.amount = amount self.load1 = load1 self.load2 = load2 } } class TaskStore : ObservableObject { @Published var tasks = [Task]() } struct Calculation: View { @State var load1 = Float() @State var load2 = Float() @State var gp : Float = 0 @State var loadA : Float = 0 @State var loadB : Float = 0 @State var rate: Float = 0 @ObservedObject var taskStore = TaskStore() @State private var birthDate = Date() @State private var time1 = Date() @State private var time2 = Date() var body: some View { NavigationView { VStack { List { Section(header:Text("负载输入")) { TextField("输入load1数值", value: $load1, format: .number) TextField("输入load2数值", value: $load2, format: .number) } HStack { Button("添加负载") { // 计算当前条目总金额 rate = load1 + load2 // 累加全局统计值 loadA += load1 loadB += load2 gp += rate // 存入任务列表,同步保存分项值 taskStore.tasks.append( Task( toDoItem: "load1: \(load1), load2: \(load2), 总金额 = \(rate) ", amount: rate, load1: load1, load2: load2 ) ) // 清空输入框 load1 = 0 load2 = 0 } } ForEach(self.taskStore.tasks) { task in Text(task.toDoItem) } .onMove(perform : self.move) .onDelete(perform : self.delete) } .navigationBarTitle("负载统计") .navigationBarItems(trailing: EditButton()) Text("Load1总负载 = \(loadA)") Text("Load2总负载 = \(loadB)") Text("总金额 = $\(gp) ") } } } func move(from source : IndexSet, to destination : Int) { taskStore.tasks.move(fromOffsets: source, toOffset: destination) } func delete(at offsets : IndexSet) { // 遍历所有待删除条目,逐个扣减对应统计值 for index in offsets { let task = taskStore.tasks[index] gp -= task.amount loadA -= task.load1 loadB -= task.load2 } taskStore.tasks.remove(atOffsets: offsets) } }
额外优化:修正了原有代码中两个输入框占位符重复的问题,添加完成后自动清空输入框,任务条目展示信息更完整。
内容的提问来源于stack exchange,提问作者Ricky Chhetri
相关产品推荐
相关产品推荐

