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

iOS 16 SwiftUI EditMode无法激活,需实现列表项选中功能

问题解决:SwiftUI EditMode 不生效+列表选中/删除/移动实现

一、先解决 EditMode 始终为 .inactive 的问题

你的代码中使用了已被 iOS 16 弃用的 NavigationView,这是导致 EditButton 无法正确同步 editMode 状态的核心原因。只需将 NavigationView 替换为 iOS 16+ 推荐的 NavigationStack 即可修复:

import SwiftUI

struct ContentView: View {
    @Environment(\.editMode) private var editMode
    @State private var name = "Maria Ruiz"

    var body: some View {
        NavigationStack { // 替换为 NavigationStack
            Form {
                if editMode?.wrappedValue.isEditing == true {
                    TextField("Name", text: $name)
                } else {
                    Text("test")
                }
            }
            .animation(nil, value: editMode?.wrappedValue)
            .toolbar {
                EditButton()
            }
        }
    }
}

点击工具栏的「Edit」按钮后,界面会切换为 TextField,editMode 状态也会正常更新为 .active。

二、实现列表项选中+保留删除/移动功能

基于上述修复,我们可以扩展实现列表的选中、删除、移动功能,完全复用系统自带的编辑控件:

import SwiftUI

// 定义列表数据模型(如果是 CoreData 实体,替换为你的 NSManagedObject 子类即可)
struct ListItem: Identifiable {
    let id = UUID()
    var title: String
}

struct ContentView: View {
    @Environment(\.editMode) private var editMode
    @State private var items = [
        ListItem(title: "Item 1"),
        ListItem(title: "Item 2"),
        ListItem(title: "Item 3"),
        ListItem(title: "Item 4")
    ]
    @State private var selectedItemIDs = Set<UUID>() // 存储选中项的ID

    var body: some View {
        NavigationStack {
            List(selection: $selectedItemIDs) { // 绑定选中集合,系统自动生成选中复选框
                ForEach(items) { item in
                    Text(item.title)
                }
                .onDelete(perform: deleteItems) // 系统自带删除功能
                .onMove(perform: moveItems) // 系统自带移动功能
            }
            .navigationTitle("List Editor")
            .toolbar {
                EditButton() // 系统自带编辑/完成切换按钮
                // 可选:添加批量操作按钮,仅在编辑模式且有选中项时显示
                if editMode?.wrappedValue.isEditing == true, !selectedItemIDs.isEmpty {
                    Button("Delete Selected") {
                        items.removeAll { selectedItemIDs.contains($0.id) }
                        selectedItemIDs.removeAll()
                    }
                }
            }
        }
    }

    // 处理删除逻辑
    private func deleteItems(at offsets: IndexSet) {
        items.remove(atOffsets: offsets)
    }

    // 处理移动逻辑
    private func moveItems(from source: IndexSet, to destination: Int) {
        items.move(fromOffsets: source, toOffset: destination)
    }
}

关键说明:

  • List(selection:):通过绑定选中项ID集合,系统会自动在编辑模式下为列表项添加选中复选框,无需自定义控件。
  • onDelete/onMove:直接复用系统自带的删除、移动交互,保持与系统一致的用户体验。
  • EditButton:自动切换编辑/完成状态,同步 editMode 环境变量,无需手动管理状态切换。

内容的提问来源于stack exchange,提问作者berger-devel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:05:14