SwiftUI中如何通过函数删除整个List Section?
SwiftUI 删除List中整个Section的实现方案
你当前的核心问题是无法获取对应Section的元素索引来构造IndexSet参数,以下是具体的修改方案:
关键修改点
- 获取元素索引:将遍历
FetchedResults的方式改为带索引的枚举形式,直接拿到每个Category在集合中的位置 - 构造IndexSet:删除按钮触发时,用当前元素的索引创建
IndexSet,传入删除函数 - 修复命名冲突:避免循环变量与全局的
listedCategory重名,同时优化可选值解包避免崩溃
修改后的完整代码
struct SampleView: View { @Environment(\.managedObjectContext) private var viewContext @Environment(\.presentationMode) var presentationMode @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Category.categoryString, ascending: false)], animation: .default) private var listedCategory: FetchedResults<Category> @State var categoryString: String = "" var body: some View { VStack{ TextField("Enter Text Here", text: $categoryString) Button { let newCategory = Category(context: viewContext) newCategory.categoryString = categoryString newCategory.typeString = "Item" // 必须设置该值,否则Section过滤条件不匹配 do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } categoryString = "" } label: { Text("Save") } List{ // 改为带索引的遍历,重命名循环变量避免冲突 ForEach(Array(listedCategory.enumerated()), id: \.element) { index, category in if category.typeString == "Item" { Section(header: Text(category.categoryString ?? "Unnamed")) { Button { // 用当前元素索引构造IndexSet deleteCategories(offsets: IndexSet(integer: index)) } label: { Text("Delete") } } } } } Spacer() } } private func deleteCategories(offsets: IndexSet) { withAnimation { offsets.map { listedCategory[$0] }.forEach(viewContext.delete) do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } }
额外说明
- 新增Category时必须设置
typeString = "Item",否则你的Section过滤条件不会匹配,新添加的内容无法显示 - 用
category.categoryString ?? "Unnamed"替代强制解包,避免因categoryString为nil导致崩溃 IndexSet(integer: index)会创建一个仅包含当前元素索引的集合,正好匹配删除函数的参数要求
内容的提问来源于stack exchange,提问作者barty9333
相关产品推荐
相关产品推荐

