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

SwiftUI:如何禁用长按拖动/滑动删除,修复EditButton无法触发编辑模式问题?

SwiftUI 禁用默认长按拖动/滑动删除,仅保留EditButton编辑模式操作

问题核心

你碰到的问题根源在于:

  • 未正确绑定编辑状态,导致EditButton点击后无法触发编辑UI(左侧红点、右侧拖动三线)
  • 未针对性禁用非编辑模式下的默认交互,长按拖动和滑动删除仍生效

完整解决方案代码

以下代码严格实现「仅通过EditButton进入编辑模式后,才能删除/重排序」的需求:

import SwiftUI

// 数据源模型
class ListDataSource: ObservableObject {
    @Published var items = ["Item 1", "Item 2", "Item 3", "Item 4"]
}

struct RestrictedEditListView: View {
    @StateObject private var dataSource = ListDataSource()
    // 绑定环境中的编辑状态
    @Environment(\.editMode) private var editMode
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(dataSource.items, id: \.self) { item in
                    Text(item)
                        // 禁用非编辑模式下的滑动删除:用空的swipeActions覆盖默认交互
                        .swipeActions(edge: .trailing, allowsFullSwipe: false) {}
                        // 禁用非编辑模式下的长按拖动:仅编辑模式返回有效拖动数据
                        .onDrag {
                            guard editMode?.wrappedValue.isEditing == true else {
                                return nil
                            }
                            return NSItemProvider(object: item as NSString)
                        }
                }
                // 仅编辑模式下启用删除操作
                .onDelete(perform: editMode?.wrappedValue.isEditing == true ? deleteItem : nil)
                // 仅编辑模式下启用重排序操作
                .onMove(perform: editMode?.wrappedValue.isEditing == true ? moveItem : nil)
            }
            .navigationTitle("专属编辑模式")
            .toolbar {
                EditButton()
            }
        }
    }
    
    // 删除逻辑
    private func deleteItem(at offsets: IndexSet) {
        dataSource.items.remove(atOffsets: offsets)
    }
    
    // 重排序逻辑
    private func moveItem(from source: IndexSet, to destination: Int) {
        dataSource.items.move(fromOffsets: source, toOffset: destination)
    }
}

关键实现说明

  1. 绑定编辑状态:通过@Environment(\.editMode)获取当前编辑模式,作为所有交互开关的判断依据。
  2. 禁用滑动删除:给列表行添加空的.swipeActions,覆盖系统默认的滑动删除交互,同时设置allowsFullSwipe: false防止误触。
  3. 禁用长按拖动:在.onDrag回调中,仅当处于编辑模式时返回有效的拖动数据,非编辑模式返回nil,系统便不会触发长按拖动。
  4. 控制编辑操作生效时机:onDelete和onMove仅在编辑模式下传入对应操作方法,非编辑时传nil,系统才会在编辑模式下显示红点和拖动三线。
  5. 导航容器依赖:确保List被NavigationStack(iOS16+)或NavigationView包裹,因为EditButton需要放在toolbar中,而toolbar必须依附于导航容器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:35:15