Swift Core Data状态管理问题:编辑Item后ItemsView不更新
问题根源
你猜的没错,问题确实出在两个ForEach的数据源上:
CategoriesView使用的FetchedResults<Category>是Core Data提供的自动监听数据变化的集合类型,任何Category的属性或关联数据变化时,都会自动触发视图更新。ItemsView里的categoryItems是从Category的items(NSSet)转换来的普通数组,这个数组不会主动发布数据变化通知;同时,ForEach遍历普通数组时,即使单个Item的属性被修改,SwiftUI也无法感知到变化——因为数组本身的元素引用没改变,且没有监听Item对象的属性更新。
解决方法
推荐两种靠谱的修复方式,选其一即可:
方法1:改用FetchRequest获取当前分类下的Item
把ItemsView的数据源换成针对当前Category的FetchRequest,利用Core Data的自动监听能力:
struct ItemsView: View { @ObservedObject var category: Category @State private var isEditingItem = false // 新增针对当前Category的FetchRequest @FetchRequest var items: FetchedResults<Item> init(category: Category) { _items = FetchRequest( sortDescriptors: [SortDescriptor(\.name)], predicate: NSPredicate(format: "category == %@", category) ) self.category = category } var body: some View { VStack { List { // 遍历FetchResults<Item> ForEach(items) { item in NavigationLink { // 保留原有逻辑 } label: { Text(item.itemName) } .contextMenu { Button { isEditingItem.toggle() } label: { Label("Edit Item", systemImage: "pencil") } } .sheet(isPresented: $isEditingItem) { EditItemView(item: item) } } } } .navigationTitle(category.categoryName) } }
方法2:让Category的关联Item集合支持SwiftUI监听
修改Category的扩展,给关联集合添加变化通知触发逻辑,同时让ForEach能跟踪单个Item的变化:
extension Category { var categoryName: String { name ?? "New Category" } var categoryItems: [Item] { get { items?.allObjects as? [Item] ?? [] } } }
然后修改ItemsView中的ForEach,添加id: \.objectID(Core Data对象的objectID是唯一且稳定的标识):
ForEach(category.categoryItems, id: \.objectID) { item in // 原有视图代码 }
这样当Item的属性变化时,SwiftUI能通过objectID识别到元素更新,触发视图刷新。
额外优化建议
EditItemView中的item建议改为@ObservedObject var item: Item,这样在编辑过程中如果有其他地方修改了该Item,视图也能实时更新:
struct EditItemView: View { @ObservedObject var item: Item // 其他代码不变 }
内容的提问来源于stack exchange,提问作者user3425711
相关产品推荐
相关产品推荐

