SwiftData修改项目名称无法持久化问题求助
问题分析与修复方案
核心问题
你的代码中,所有修改操作(名称、数量、完成状态)都仅修改了本地@State变量的副本,没有同步到SwiftData的Einkauf模型对象,因此这些更改无法被持久化保存。新增功能正常是因为你直接通过ModelContext插入了新的模型对象。
具体修复步骤
1. 重构EinkaufItemRowView,直接绑定模型对象
不要单独传递name、anzahl等属性,直接传入Einkauf模型实例,用@Bindable包装(SwiftData的@Model类默认遵循Observable协议,@Bindable可实现视图与模型属性的双向绑定)。
修改后的EinkaufItemRowView:
struct EinkaufItemRowView: View { @Bindable var item: Einkauf @State private var isDone: Bool init(item: Einkauf) { self.item = item // 初始化时同步模型的完成状态到本地State self._isDone = State(initialValue: item.isDone ?? false) } var body: some View { HStack { Image(systemName: isDone ? "checkmark.circle.fill" : "checkmark.circle") .resizable() .frame(width: 30, height: 30) .foregroundStyle(isDone ? .green : .primary) .padding(.horizontal) .onTapGesture { isDone.toggle() item.isDone = isDone // 将状态同步到模型 } // 直接绑定模型的name属性,修改时自动同步 TextField(item.name, text: $item.name) .strikethrough(isDone) .font(.title2) Spacer() Button(action: { guard item.anzahl > 0 else { return } item.anzahl -= 1 // 直接修改模型的数量属性 }, label: { Image(systemName: "minus.circle") .resizable() .foregroundStyle(.red) .frame(width: 30, height: 30) }) Button(action: { item.anzahl += 1 // 直接修改模型的数量属性 }, label: { Image(systemName: "plus.circle") .resizable() .foregroundStyle(.green) .frame(width: 30, height: 30) }) // 直接显示模型中的数量值 Text("\(item.anzahl)") .frame(width: 40) .padding(.horizontal, 5) .font(.title2) .bold() } } }
2. 调整EinkaufslisteDetailView的列表渲染逻辑
在ForEach中直接传递Einkauf实例给行视图,移除无用的本地状态变量:
struct EinkaufslisteDetailView: View { @Environment (\.modelContext) var context @ObservedObject var vm: EinkaufViewModel @Query var items2: [Einkauf] let kategorieName: String var body: some View { NavigationStack { List { ForEach(items2) { item in EinkaufItemRowView(item: item) .padding(.vertical) } .onDelete { indexSet in for index in indexSet { context.delete(items2[index]) } } } .listStyle(.plain) .navigationBarItems( trailing: Button(action: { vm.addItem(context: context) }, label: { Image(systemName: "plus.circle") .resizable() .frame(width: 30, height: 30) }) ) .navigationTitle(kategorieName) } } }
3. 确保Einkauf模型定义完整
你的Einkauf模型需要包含对应属性,示例如下:
@Model class Einkauf { var name: String var anzahl: Int var isDone: Bool? // 根据需求设置为可选或非可选 init(name: String, anzahl: Int, isDone: Bool? = false) { self.name = name self.anzahl = anzahl self.isDone = isDone } }
关键原理
SwiftData的持久化依赖于修改@Model标记的对象属性,ModelContext会自动跟踪这些更改并完成保存。如果仅修改本地@State变量的副本,这些更改不会同步到模型对象,自然无法被持久化。使用@Bindable可以让视图直接绑定模型属性,修改操作会自动同步到模型,由SwiftData负责持久化。
内容的提问来源于stack exchange,提问作者TheRiser
相关产品推荐
相关产品推荐

