【问题标题】:Navigating to detail views in SwiftUI using core data使用核心数据导航到 SwiftUI 中的详细视图
【发布时间】:2019-12-22 08:57:56
【问题描述】:

我正在尝试构建一个示例 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 on 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 文件设置的。

如果有帮助的话,我非常乐意添加任何额外/省略的代码,例如我如何写入/读取核心数据。

【问题讨论】:

  • 我认为这不是与 CoreData 相关的问题,但为了让我们复制粘贴您的示例并尝试找出问题,我们需要所有代码作为最小可行示例.例如:缺少 Cook 类,我无法真正复制您的代码并尝试调试它。
  • cook.protein 是可选的吗?您可以将{ cook in 替换为{ (cook: CookType) in。从标签周围移除VStack。如果两个参数之一是标签,它更有可能起作用。如果您尝试传入绑定,它可能会变得更加复杂。特别是如果它由计算数组支持的话..但我们不要讨论这个。哦,你可以添加cook.protein 作为第一个未命名的参数,这更有可能工作,同时删除尾随闭包。耶。 SwiftUI!
  • 由于我们看不到您的其余代码,请看一下这个项目。它是完整的,可以在 Beta 5 上编译和运行。它可能会给您一些关于项目方向的想法。 github.com/Whiffer/SwiftUI-Core-Data-Test

标签: core-data swiftui


【解决方案1】:

我完全可以理解您对 Xcode 错误消息的不满。实际错误通常与错误消息相去甚远。 [建议:在每次干净编译后使用源代码控制和提交;-)] 您在列表视图中遇到的错误是因为您在详细视图的参数列表中指定了错误的类型。请尝试以下操作:

struct CookDetailView: View {

    var cook: CookViewModel

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

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

这个答案适用于 Beta 5。在未来的 Beta 中情况肯定会发生变化。

【讨论】:

  • 解决了!你不会相信我在这个问题上撞了多久。非常感谢您的解决方案以及示例项目和提示 - 这一切都非常有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
相关资源
最近更新 更多