You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI待办列表使用offsets删除时出现删错项问题求助

解决待办事项删除时索引不匹配的问题

你的核心问题是:onDelete传入的offsets是当前Section内显示任务的索引,而非原始tasks数组的索引。视图中显示的是经过筛选(tasksForDay(day))、排序后的任务子集,和原始数组的顺序/内容不匹配,直接用这个偏移量删原始数组自然会删错行。

修复步骤

1. 让TaskItem遵循Equatable协议

如果你的TaskItem还没实现,先添加协议支持(通过ID匹配任务实例):

struct TaskItem: Identifiable, Equatable {
    let id = UUID()
    var taskName: String
    var date: Date
    var priority: Int
    var isCompleted: Bool

    static func == (lhs: TaskItem, rhs: TaskItem) -> Bool {
        lhs.id == rhs.id
    }
}

2. 重构删除方法

修改deleteTasks,让它先获取当前Section对应的任务列表,再通过实例匹配从原始数组中删除:

private func deleteTasks(for day: Date, at offsets: IndexSet) {
    // 获取当前Section显示的任务列表
    let targetTasks = offsets.map { tasksForDay(day)[$0] }
    // 从原始数组中移除匹配的任务
    tasks.removeAll { targetTasks.contains($0) }
    saveTasksToUserDefaults()
    tasks.sort(by: <)
}

3. 更新视图中的onDelete调用

在Section的onDelete中传入当前日期参数:

NavigationView {
    List {
        ForEach(sortedTasksByDay, id: \.self) { day in
            if !isOtherDatesHidden || Calendar.current.isDateInToday(day) {
                Section(header: Text(day.formattedDate)) {
                    ForEach(tasksForDay(day)) { task in
                        if !isTaskHidden(task) {
                            TaskRowView(task: task)
                                .onTapGesture {
                                    toggleTaskCompletion(task)
                                }
                        }
                    }
                    // 传入当前日期,调用重构后的删除方法
                    .onDelete(perform: { offsets in
                        deleteTasks(for: day, at: offsets)
                    })
                }
            }
        }
    }
}

补充说明

你之前的排序逻辑本身没有问题,但删除操作的索引不匹配才是核心矛盾。现在通过任务实例匹配而非索引操作,彻底避免了视图显示序列和原始数组序列不一致导致的删错问题。

内容的提问来源于stack exchange,提问作者November Avanza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:07:24