SwiftUI分Section列表中跨分组Realm任务项的onDelete删除实现
分区块Realm任务列表精准删除实现方案
问题场景
基于SwiftUI构建分两类区块展示的待办清单视图:
- 区块分为
pending(待处理)、completed(已完成)两类 - 数据层使用Realm存储,通过
@ObservedResults订阅任务数据 - 滑动删除时需要解决跨分组索引错位问题,精准定位待删除的目标任务
初始待补全逻辑的代码如下:
enum Sections: String, CaseIterable { case pending = "Pending" case completed = "Completed" } struct TodoListView: View { @ObservedResults(Task.self) var tasks: Results<Task> var pendingTasks: [Task] { tasks.filter { $0.isCompleted == false } } var completedTasks: [Task] { tasks.filter { $0.isCompleted == true } } var body: some View { let _ = print(Self._printChanges()) List { ForEach(Sections.allCases, id: \.self) { section in Section { let filteredTasks = section == .pending ? pendingTasks: completedTasks if filteredTasks.isEmpty { Text("No tasks") } ForEach(filteredTasks, id: \._id) { task in HStack { TaskCellView(task: task) } }.onDelete { indexSet in // 待实现删除逻辑 } } header: { Text(section.rawValue) } } }.listStyle(.plain) } }
实现逻辑说明
onDelete回调返回的indexSet是当前Section内部的局部索引,不是整个List的全局索引,因此只需要获取当前分组对应的筛选后任务数组,按索引取出对应任务调用Realm删除方法即可,不会出现索引错位删错的问题。
最简实现(推荐)
直接复用当前Section作用域内已经计算完成的filteredTasks变量,无需重复做筛选计算,代码更简洁:
.onDelete { indexSet in indexSet.forEach { index in let targetTask = filteredTasks[index] $tasks.remove(targetTask) } }
已验证可运行的冗余实现(自行编写版本)
以下代码可以正常运行,但存在重复筛选的冗余计算,不推荐:
.onDelete { indexSet in var filteredTasks: [Task] = [] switch section { case .pending: filteredTasks = tasks.filter { $0.isCompleted == false } case .completed: filteredTasks = tasks.filter { $0.isCompleted == true } } indexSet.forEach { index in let task = filteredTasks[index] $tasks.remove(task) } }
避坑提示:禁止直接用全局
tasks数组按indexSet的索引取元素,否则会因为跨分组导致索引错位,误删其他分组的任务。
内容的提问来源于stack exchange,提问作者Mary Doe
相关产品推荐
相关产品推荐

