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

SwiftUI弹窗关闭后如何立即刷新Core Data列表?

Core Data 添加数据后列表不实时更新的解决方案

问题描述

我用Core Data实现水果的永久存储和列表展示,包含ContentView主界面和作为弹窗的SecondScreen。在SecondScreen输入水果点击保存后,希望ContentView的列表能立刻显示新添加的水果,但现在点击保存后新水果不会马上出现,必须重启应用才能看到。我尝试在ContentView里加了@State变量refresh并和SecondScreen绑定,点击保存时切换这个变量触发刷新,但没效果。

问题分析

  • 核心问题是ContentView和SecondScreen各自创建了独立的CoreDataViewModel实例:SecondScreen里添加数据的操作是在自己的vm实例上执行的,ContentView的vm完全感知不到数据变化。
  • 你尝试的refresh变量无效,因为ContentView的列表是基于vm.savedEntities渲染的,refresh变量没有关联到重新获取数据的逻辑,而且就算关联了,两个vm实例的数据本来就是分开的,刷新也拿不到新数据。

解决方案

  • 让SecondScreen复用ContentView的CoreDataViewModel实例,不要自己新建。
  • 移除多余的refresh变量,利用@Published属性的自动刷新机制,当savedEntities更新时SwiftUI会自动更新列表。

修改后的代码

ContentView 结构体

struct ContentView: View {
    // sheet控制变量
    @State var showSheet: Bool = false
    
    @StateObject var vm = CoreDataViewModel()
    
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                Button(action: {
                    showSheet.toggle()
                }, label: {
                    Text("Add Fruit")
                })
                
                List {
                    ForEach(vm.savedEntities) { entity in
                        Text(entity.name ?? "NO NAME")
                    }
                }
            }
            .navigationTitle("Fruits")
            .sheet(isPresented: $showSheet, content: {
                // 将ContentView的vm传递给SecondScreen
                SecondScreen(vm: vm)
            })
        }
    }
}

SecondScreen 结构体

struct SecondScreen: View {
    // 接收ContentView传递过来的ViewModel实例
    @ObservedObject var vm: CoreDataViewModel
    
    @Environment(\.dismiss) var dismiss // iOS15+ 推荐使用该API关闭弹窗
    
    @State var textFieldText: String = ""
    
    var body: some View {
        TextField("Add fruit here...", text: $textFieldText)
            .font(.headline)
            .padding(.horizontal)
        
        Button(action: {
            guard !textFieldText.isEmpty else { return }
            vm.addFruit(text: textFieldText) // 使用共享的vm添加数据
            textFieldText = ""
            dismiss() // 关闭弹窗
        }, label: {
            Text("Save")
        })
    }
}

效果说明

修改后,SecondScreen使用的是和ContentView同一个CoreDataViewModel实例,添加数据后调用的saveData方法会重新获取数据并更新@Published修饰的savedEntities,SwiftUI会自动检测到这个变化并刷新ContentView的列表,实现添加数据后的实时更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:21:00