SwiftUI:核心数据列表不会随着关系属性的更改而更新

问题描述 投票:0回答:1

我有一个简单的用例,其中我有一个带有

Item
(具有“timestamp”属性)的核心数据模型以及与
Tag
(具有“tagName”属性)的一对一关系。我想使用 SwiftUI 显示项目列表,并在每一行中显示项目的时间戳和 tag.tagName(如果可用)。

我遇到的问题是,如果我更新与某个项目关联的 tagName,它不会在 SwiftUI 视图中自动刷新。对

Item
的任何更新都会自动刷新,如果我重新启动应用程序,它也会获取更改......但它不会自动发生。

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            
            List {
                Section {
                    ForEach(items) { item in
                            
                        VStack (alignment: .leading){
                            Text(item.timestamp!, formatter: itemFormatter)
                            
                            if let tag = item.tag, let name = tag.tagName {
                                Text("Tag: \(name)")
                            }
                        }
                    }
                    .onDelete(perform: deleteItems)
                } header: {
                    Text("Items")
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
                
                ToolbarItem (placement: .navigationBarLeading) {
                    Button(action: addTagItem) {
                        Label("Add Tag", systemImage: "tag")
                    }
                }
                ToolbarItem(placement: .navigationBarLeading) {
                    Button(action: editTagItem) {
                        Label("Change Tag Name", systemImage: "phone")
                    }
                }
            }
        }
   }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
            
            try? viewContext.save()
        }
    }

    private func addTagItem() {
        withAnimation {
            let newItem = Tag(context: viewContext)
            newItem.tagName = "Design"

            if let item = items.first {
                item.tag = newItem
            }
            try? viewContext.save()
        }
    }
    private func editTagItem() {
        withAnimation {
            if let item = items.first, let tag = item.tag  {
                tag.tagName = "changed"
            }
            
            try? viewContext.save() // <-- should update the List, but doesn't
            
            if let item = items.first, let tag = item.tag {
                tag.objectWillChange.send() // tried this, doesn't work
            }
            
        }
    }
}

我添加了工具栏按钮来测试添加新项目、新标签并将第一个项目的标签设置为第一个标签,然后设置一个更改标签名称的场景。前 2 个函数工作正常,但更改 tagName 不会更新列表视图。

看起来 SwiftUI

@FetchRequest
只监听对
Item
的更改。我想这与
NSFetchedResultsController
类似,它会做同样的事情,但我希望 SwiftUI 能够改善这种情况。在我查看的其他问题中,
objectWillChange.send
似乎有帮助,但它似乎并没有解决我的问题。

无论如何,如果关系属性发生更改,刷新完整列表的最佳方法是什么?

swiftui core-data swiftui-list
1个回答
0
投票

只需使用

@ObservedObject var tag: Tag

© www.soinside.com 2019 - 2024. All rights reserved.