The correct way to list CoreData object in nest NavigationView in NavigationLink

Viewed 274

In xcode 12 (swift 5.3), I using the conditional navigationLink navigate to another navigationView to list coreData object with NavigationLink. But it seems the AnotherView's NavigationTitle can not be correctly show at the top of screen, instead it padding to the top. The list in another navigationView have a external white background color. The something.id which I want to pass to SomethingView report Argument passed to call that takes no arguments error, but I can get something.name in Text.

struct StartView: View {
    @State var changeToAnotherView: String? = nil
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                ...
                NavigationLink(destination: AnotherView(), tag: "AnotherView",
                               selection: $changeToAnotherView) { EmptyView() }
            }
        }
    }
}

struct AnotherView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Something.entity(), sortDescriptors: []) var somethings: FetchedResults<Something>
    ...
    var body: some View {
        NavigationView {
            List {
                ForEach(self.somethings, id: \.id) { something in
                    NavigationLink(destination: SomethingView(somethingID: something.id)) {
                        Text(something.name ?? "unknown name")
                    }
                }
            }
            .navigationBarTitle("SomethingList")
        }
    }
}
1 Answers

You don't need second NavigationView - it must be only one in view hierarchy, as well it is better to pass CoreData object by reference (view will be able to observe it), so

struct AnotherView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Something.entity(), sortDescriptors: []) var somethings: FetchedResults<Something>
    ...
    var body: some View {
        List {
            ForEach(self.somethings, id: \.id) { something in
                NavigationLink(destination: SomethingView(something: something)) {
                    Text(something.name ?? "unknown name")
                }
            }
        }
        .navigationBarTitle("SomethingList")
    }
}

struct SomethingView: View {
   @ObservedObject var something: Something

   var body: some View {

   // .. your next code
Related