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

iOS15下SwiftUI的editMode.onDelete与自定义swipeActions共存问题

解决方案

根因说明

SwiftUI 自 iOS 15 引入swipeActions后,只要为列表行添加了自定义滑动操作,系统就会默认接管行的所有滑动手势响应,原生onDelete提供的左滑删除手势会被自动覆盖,属于框架的设计行为。

方案1:iOS 15+ 适配(保留原生editMode与swipeActions)

无需放弃原有能力,只需将删除操作也显式声明为trailing侧的自定义滑动操作,同时保留onDelete、onMove以支持编辑模式下的批量操作:

import SwiftUI
import PlaygroundSupport

struct SomeList: Identifiable {
    let id: UUID = UUID()
    var name: String
}

struct ContentView: View {
    @State private var editMode = EditMode.inactive
    @State private var someList: [SomeList] = [
        SomeList(name: "row1"),
        SomeList(name: "row2"),
        SomeList(name: "row3")
    ]
    
    var body: some View {
        NavigationView {
            List {
                // 改为带索引的遍历,方便单条滑动删除时定位元素
                ForEach(Array(someList.enumerated()), id: \.element.id) { index, someElement in
                    Text(someElement.name)
                        // leading侧右滑编辑
                        .swipeActions(edge: .leading) {
                            Button("Edit") {
                                // 你的编辑逻辑
                            }
                            .tint(.blue)
                        }
                        // trailing侧左滑删除
                        .swipeActions(edge: .trailing) {
                            Button("Delete", role: .destructive) {
                                someList.remove(at: index)
                            }
                        }
                }
                // 保留onDelete、onMove,用于编辑模式下的批量操作
                .onDelete { indexSet in
                    someList.remove(atOffsets: indexSet)
                }
                .onMove { source, destination in
                    someList.move(fromOffsets: source, toOffset: destination)
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    EditButton()
                }
            }
            .environment(\.editMode, $editMode)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

该方案实现效果完全匹配需求:

  • 非编辑模式下:右滑出编辑按钮,左滑出删除按钮
  • 点击EditButton进入编辑模式后:依然支持批量选中删除、行拖动排序

方案2:兼容iOS 13+ 低版本适配

如果需要支持iOS15以下系统,放弃swipeActions改用自定义实现即可:

  • 用DragGesture监听列表行的水平偏移,偏移达到阈值后显示对应操作按钮,松手后自动归位/触发操作
  • 原生editMode的onDelete、onMove能力可以完全保留,不受自定义手势影响
  • 也可以封装UIKit的UITableViewRowAction实现滑动操作,稳定性更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:36:01