使用核心数据导航到SwiftUI中的详细视图

时间:2019-08-16 00:56:54

标签: core-data swiftui

我正在尝试构建一个示例BBQ应用程序以学习SwiftUI(XCode 11 beta 5),并且一直无法弄清楚如何从Core Data的对象列表视图中导航到对象的详细信息视图。 Xcode没有帮助,根据我的尝试,大多数情况下会弹出不相关的错误。

我已尝试尽我所能来应用状态,绑定,可观察对象等,但未能破解。

这是我的列表视图,构建起来很好,并允许我导航到目的地(这是一个包含id属性作为字符串的视图)

struct CookListView: View {

    @ObservedObject var cookListVM: CookListViewModel
    @State var cookCreatorVM = CookCreatorViewModel()

    init() {
        cookListVM = CookListViewModel()
    }

    var body: some View {


        NavigationView {
            List {
                ForEach(cookListVM.cooks, id: \.id) { cook in
                    NavigationLink(destination: Text("\(cook.id)")) {
                        VStack {
                            Text(cook.protein)
                        }
                    }
                }
            }.navigationBarTitle("BBQ")
        }
    }
}

但是,如果我这样更改NavigationLink目的地:

NavigationView {
    List {
        ForEach(cookListVM.cooks, id: \.id) { cook in
            NavigationLink(destination: CookDetailView(cook: cook)) {
                VStack {
                    Text(cook.protein)
                }
            }
        }
    }
}

Xcode将不再生成项目。它给我的错误似乎无关紧要,例如ForEach行上的Type '_' has no member 'id',或者如果我从ForEach中删除, id: \.id(由于Identifiable我并不需要),我会得到Type of expression is ambiguous without more context行上的Text(cook.protein)

如果我使用硬编码的数组,它将建立并且可以很好地导航。该问题仅在我尝试使用Core Data时出现。

我的CookDetailView如下:

struct CookDetailView: View {
    var cook: Cook
    var body: some View {
        VStack {
            Text("\(cook.protein!)")
        }
    }
}

Cook对象本身的模型如下所示:

class CookViewModel: ObservableObject, Identifiable {

    var protein: String = ""
    var type: String = ""
    var id: UUID = UUID()

    init(cook: Cook){
        self.protein = cook.protein!
        self.type = cook.type!
        self.id = UUID()
    }
}

它也是通过.xcdatamodeld文件设置的。

如果有帮助,我很乐意添加任何其他/省略的代码,例如我如何写入/读取核心数据。

1 个答案:

答案 0 :(得分:0)

对于您对Xcode的错误消息的不满,我可以完全确定。实际错误通常离错误消息不远。 [建议:在每次干净编译后使用源代码管理并提交;-)]出现在列表视图中的错误是因为在详细信息视图的参数列表中指定了错误的类型。请尝试以下操作:

struct CookDetailView: View {

    var cook: CookViewModel

    var body: some View {
        VStack {
            Text("\(cook.name)")
        }
    }
}

顺便说一句,由于您要获取一个数组,因此除非您手动发布它们,否则您将不会观察到该数组中的更改。我放弃尝试让我的NSManagedObject子类发布它们自己的更改。有两种解决方法。您可以从NSFetchedResultsController的controllerDidChangeContent委托中调用objectWillChange,或者在不使用获取的结果控制器时观察NSManagedObjectContextDidSave通知时也可以这样做。

此答案适用于Beta5。将来的Beta中,情况肯定会发生变化。