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

SwiftUI待办清单App实现列表项拖拽手势:右滑完成左滑删除

SwiftUI 待办清单左右滑手势实现方案

实现逻辑说明

我们采用SwiftUI 15.0+内置的swipeActions修饰器实现需求,无需自定义复杂拖拽手势,逻辑清晰易维护:

  • 右滑待办项触发leading侧操作:将任务移至已完成列表,后续可直接给CompleteVC绑定已完成列表数据源
  • 左滑待办项触发trailing侧操作:直接删除对应待办项

前置补全代码(你现有代码缺失的Task和TaskStore定义)

import SwiftUI
import Combine

// 任务模型
struct Task: Identifiable {
    let id: String
    let toDoItem: String
    var isCompleted: Bool = false // 新增完成状态标识
}

// 数据管理类
class TaskStore: ObservableObject {
    @Published var tasks: [Task] = [] // 待办任务列表
    @Published var completedTasks: [Task] = [] // 已完成任务列表,CompleteVC直接用这个数组渲染即可
}

修改后的ContentView完整代码

struct ContentView: View {
    @ObservedObject var taskStore = TaskStore()
    @State var newToDo : String = ""
    
    var searchBar : some View {
        HStack {
            TextField("Enter in a new task", text: self.$newToDo)
            Button(action: self.addNewToDo, label: {
                Text("Add New")
            })
        }
    }
    
    func addNewToDo() {
        guard !newToDo.isEmpty else { return }
        taskStore.tasks.append(Task(id: String(taskStore.tasks.count + 1), toDoItem: newToDo))
        self.newToDo = ""
    }
    
    var body: some View {
        NavigationView {
            VStack {
                searchBar.padding()
                List {
                    ForEach(self.taskStore.tasks) { task in
                        Text(task.toDoItem)
                            // 核心:添加左右滑操作
                            .swipeActions(edge: .leading, allowsFullSwipe: true) { // 右滑触发
                                Button {
                                    markAsCompleted(task: task)
                                } label: {
                                    Label("完成", systemImage: "checkmark.circle.fill")
                                }
                                .tint(.green)
                            }
                            .swipeActions(edge: .trailing, allowsFullSwipe: true) { // 左滑触发
                                Button(role: .destructive) {
                                    deleteTask(task: task)
                                } label: {
                                    Label("删除", systemImage: "trash.fill")
                                }
                            }
                    }.onMove(perform: self.move)
                }.navigationBarTitle("Tasks")
                .navigationBarItems(trailing: EditButton())
            }
        }
    }
    
    // 标记为已完成的方法
    func markAsCompleted(task: Task) {
        guard let index = taskStore.tasks.firstIndex(where: { $0.id == task.id }) else { return }
        var completedTask = taskStore.tasks.remove(at: index)
        completedTask.isCompleted = true
        taskStore.completedTasks.append(completedTask)
    }
    
    // 删除单个任务的方法
    func deleteTask(task: Task) {
        guard let index = taskStore.tasks.firstIndex(where: { $0.id == task.id }) else { return }
        taskStore.tasks.remove(at: index)
    }
    
    func move(from source : IndexSet, to destination : Int) {
        taskStore.tasks.move(fromOffsets: source, toOffset: destination)
    }
    
    // 原批量删除方法保留,供编辑模式使用
    func delete(at offsets : IndexSet) {
        taskStore.tasks.remove(atOffsets: offsets)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

核心改动说明

  • 新增completedTasks数组存储已完成任务,后续开发CompleteVC时直接绑定该数组即可渲染已完成列表
  • 用swipeActions分别配置左右滑操作,支持全屏滑动触发,符合系统原生交互逻辑
  • 单独封装单个任务的完成、删除方法,逻辑解耦,后续扩展功能更方便

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:09:03