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
相关产品推荐
相关产品推荐

