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

Core Data中Int32类型属性修改后Text不立即更新如何解决?

问题根源

这个问题和闭包无关,也不需要替换整个数组,核心原因是你没有对ForEach循环内的Core Data实体实例做属性变更监听:

  • Core Data生成的实体类本身是ObservableObject子类,@StateObject只会在你监听的exeplan本身的属性/关系发生变更时触发刷新(比如你给exercisearray新增/删除元素)
  • 你现在修改的是exercisearray内部元素的duration属性,上层的exeplan不会感知到这次变更,所以当前视图不会重绘,只有页面重新初始化时才会读取最新值。

最优解决方案

把列表单项抽成独立子视图,在子视图中用@ObservedObject接收对应的实体实例,子视图会自动监听实体的属性变更,触发实时刷新:

// 抽离的单项视图
struct ExerciseItemView: View {
    // 监听单个Exercise实体的属性变化
    @ObservedObject var item: Exercise
    @Environment(\.managedObjectContext) private var viewContext
    
    var body: some View {
        HStack {
            Button {
                item.duration -= 15
                do {
                    try viewContext.save()
                } catch {
                    print(error.localizedDescription)
                }
            } label: {
                Image(systemName: "minus.circle.fill")
            }
            
            Text("\(item.duration)")
            
            Button {
                item.duration += 15
                do {
                    try viewContext.save()
                } catch {
                    print(error.localizedDescription)
                }
            } label: {
                Image(systemName: "plus.circle.fill")
            }
        }
    }
}

// 原页面的ForEach替换为以下写法
ForEach(Array(exeplan.exercisearray.enumerated()), id: \.element) { _, item in
    ExerciseItemView(item: item as! Exercise)
}

临时应急方案

如果不想抽离子视图,可以加一个无实际意义的@State变量,每次修改属性后手动触发视图刷新,该方案不推荐长期使用:

// 当前页面新增变量
@State private var refreshFlag = false

// 修改按钮的action
Button(action: {
    item.duration -= 15
    do {
        try viewContext.save()
        refreshFlag.toggle() // 手动触发重绘
    } catch {} 
}, label: {
    Image(systemName: "minus.circle.fill")
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:45:02