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

SwiftUI中如何通过函数删除整个List Section?

SwiftUI 删除List中整个Section的实现方案

你当前的核心问题是无法获取对应Section的元素索引来构造IndexSet参数,以下是具体的修改方案:

关键修改点

  1. 获取元素索引:将遍历FetchedResults的方式改为带索引的枚举形式,直接拿到每个Category在集合中的位置
  2. 构造IndexSet:删除按钮触发时,用当前元素的索引创建IndexSet,传入删除函数
  3. 修复命名冲突:避免循环变量与全局的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:50:41