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

SwiftUI如何仅在EditMode下启用列表Delete滑动删除手势

禁用NavigationView列表非编辑态滑动删除、仅保留编辑模式删除能力的实现方案

问题背景

需求为屏蔽NavigationView中列表项默认的左滑呼出Delete按钮的操作,仅当NavigationView进入编辑模式时,才开放列表项删除能力。
已尝试的无效方案:

  • 基于editMode环境变量判断,给onDelete修饰符条件传入删除闭包或nil,未生效
  • 调用deleteDisabled修饰符,传入绑定editMode状态的判断值,修饰符未响应editMode变化,始终保持初始状态的禁用逻辑

问题复现代码

@State private var list = [1,2,3,4,5]
@State private var editMode = EditMode.inactive
    
var body: some View {
   NavigationView {
      List {
         ForEach(list, id: \.self) { item in
            Text("\(item) \(String(self.editMode.isEditing))")
         }
         .onDelete(perform: self.editMode.isEditing ? { index in list.remove(atOffsets: index) } : nil)
         .deleteDisabled(!self.editMode.isEditing) // 始终保持删除禁用,编辑模式下也不生效
      }
      .navigationBarItems(leading: EditButton(), trailing: Text(editMode == .active ? "Editing" : "Not Editing"))
      .environment(\.editMode, $editMode)
  }
}

异常表现

editMode状态变化时,列表项内展示的编辑状态文本、导航栏尾部的状态提示文本均可正常更新,但同一作用域下的onDelete、deleteDisabled修饰符完全不响应editMode变化,不会同步更新逻辑。
测试环境:Xcode 14.0 Beta

修复方案

该异常是Xcode 14 Beta版本下SwiftUI列表修饰符的状态刷新缺陷导致:onDelete、deleteDisabled不会跟随editMode变化重新计算入参,只需给ForEach添加绑定编辑状态的id修饰符,强制编辑模式切换时重绘ForEach内容即可让修饰符的判断逻辑生效。
修复后可运行代码:

@State private var list = [1,2,3,4,5]
@State private var editMode = EditMode.inactive
    
var body: some View {
   NavigationView {
      List {
         ForEach(list, id: \.self) { item in
            Text("\(item) \(String(self.editMode.isEditing))")
         }
         .id(editMode.isEditing) // 编辑状态变化时强制重绘ForEach,触发修饰符逻辑更新
         .onDelete(perform: editMode.isEditing ? { index in
             list.remove(atOffsets: index)
         } : nil)
         .deleteDisabled(!editMode.isEditing)
      }
      .navigationBarItems(leading: EditButton(), trailing: Text(editMode == .active ? "Editing" : "Not Editing"))
      .environment(\.editMode, $editMode)
  }
}

实现说明

  • 非编辑状态下onDelete传入nil会直接屏蔽左滑呼出Delete按钮的系统交互,无需自定义手势拦截
  • 进入编辑模式后,onDelete正常传入删除闭包,列表行左侧会展示系统默认的删除减号控件,点击即可触发删除逻辑
  • 如果正式版Xcode中仍存在状态不同步问题,可将自定义的@State类型editMode替换为系统注入的@Environment(\.editMode) var editMode,避免自定义状态和系统EditButton的状态同步冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:51:26