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

SwiftData NavigationSplitView中onDelete无法可靠删除列表项求助

SwiftData在iPad横屏NavigationSplitView中删除列表项后随机重现的问题修复

问题根源分析

  1. 错误的删除逻辑:原代码中onDelete仅当要删除的项等于当前选中项时才执行删除,这意味着大多数滑动删除操作实际未生效——删除的项看似消失只是视图临时刷新,后续切换选中项时,未被真正删除的项会重新出现。
  2. 强引用残留:若已删除的项仍被selectedThing持有强引用,SwiftData无法正确回收该对象,在视图状态更新时会重新将其纳入查询结果。
  3. 上下文未及时同步:插入或删除对象后未立即保存上下文,导致数据状态与视图显示不同步,加剧了内容重现的问题。

修复后的代码

修正ContentView中的核心逻辑

struct ContentView: View {

    @Environment(\.modelContext) private var context
    @Query(sort: \Thing.name, order: .forward) var things: [Thing]

    @State private var selectedThing: Thing?

    var body: some View {
    
        NavigationSplitView {
            VStack {
                Text("Some Things")
                List(selection: $selectedThing) {
                    ForEach(things, id: \.self) { thing in
                            HStack {
                                Text(thing.name)
                                Text(thing.areYouSure.description)
                            }
                    }
                    .onDelete{ indexSet in
                        indexSet.forEach { index in
                            let targetThing = things[index]
                            // 若要删除的是当前选中项,清空选中状态解除强引用
                            if targetThing == selectedThing {
                                selectedThing = nil
                            }
                            context.delete(targetThing)
                        }
                        // 立即保存上下文确保状态同步
                        do {
                            try context.save()
                        } catch {
                            print(error)
                        }
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        AddFourThings()
                    } label: {
                        Image(systemName: "plus")
                    }
                }
            }
        } detail: {
            ZStack {
                if let selectedThing {
                    DetailView(thing: selectedThing)
                } else {
                    Text("Choose a Thing")
                }
            }
        }
    
    }

    private func AddFourThings() {
    
        let thing1 = Thing(name: "Thing One", areYouSure: true)
        let thing2 = Thing(name: "Thing Two", areYouSure: false)
        let thing3 = Thing(name: "Thing Three", areYouSure: true)
        let thing4 = Thing(name: "Thing Four", areYouSure: false)
    
        context.insert(thing1)
        context.insert(thing2)
        context.insert(thing3)
        context.insert(thing4)
        
        // 插入后保存上下文,避免数据同步延迟
        do {
            try context.save()
        } catch {
            print(error)
        }
    
    }

}

其余代码保持不变

DetailView和Thing模型无需修改,确保Thing类正确标记@Model即可。

额外注意事项

  • 由于当前使用的是Xcode 15 Beta版本,若修复后仍存在问题,可能是SwiftData的Beta版bug,可尝试更新至最新Beta版本,或通过context.refreshAll()在合适时机强制刷新上下文状态。
  • 避免在视图层长期持有SwiftData模型对象的强引用,尽量通过@Query或上下文查询获取最新状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:28:13