2

I'm trying to generate a ForEach with a NavigationLink and use State and Binding to pass some entity around:

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

    @FetchRequest(
        entity: MyEntity.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \MyEntity.name, ascending: true)
        ]

    ) var entries: FetchedResults<MyEntity>

    var body: some View {
        NavigationView {
            List {
                ForEach(entries, id: \.self) { (entry: MyEntity) in
                    NavigationLink(destination: DetailView(myEntry: $entry)) {
                        Text(entry.name!)
                    }
                }.
            }
        }
    }
}

And then the following view:

struct DetailView: View {
    @Binding var myEntry: MyEntity

    var body: some View {
        Text(myEntry.name!)
    }
}

The problem is I can not pass the value to Detail view since the error:

Use of unresolved identifier '$entry'

What is wrong here and how to solve this?

If I just have a simple @State its no problem to pass it via the binding, but I want/need to use it in the ForEach for the FetchedResults

EDIT: If I remove the $ I get Cannot convert value of type 'MyEntity' to expected argument type 'Binding<MyEntity>'

EDIT2: The purpose is to pass some object to DetailView and then pass it back later to ContentView

gurehbgui
  • 14,236
  • 32
  • 106
  • 178
  • check the type of entry which is provided in initialization closure by ForEach. Does MyEntity type provided its binding via its projectedValue property? That is what $ in front of entry means. – user3441734 Feb 23 '20 at 11:25
  • I can't understand. The MyEntity is a CoreData Element – gurehbgui Feb 23 '20 at 11:28
  • If I remove the $ I get: Cannot convert value of type 'MyEntity' to expected argument type 'Binding' – gurehbgui Feb 23 '20 at 11:29
  • thats because you define it as parameter of DetailView. But MyEntity is not Binding. with $entity compiler complain, because it doesn't exists. $ is shortcut to projectedValue, see property wrappers definition – user3441734 Feb 23 '20 at 11:34
  • So what I need to to since I not only need it in DetailView but I also need to pass is back later to ContentView – gurehbgui Feb 23 '20 at 11:36
  • it is some reference type, so you can modify it, if you like. – user3441734 Feb 23 '20 at 11:42

2 Answers2

2

Use the following in ForEach

   ForEach(entries, id: \.self) { entry in
        NavigationLink(destination: DetailView(myEntry: entry)) {
            Text(entry.name!)
        }
    }

and the following in DetailView

struct DetailView: View {
    var myEntry: MyEntity

    var body: some View {
        Text(myEntry.name!)
    }
}

The MyEntity is class, so you pass object by reference and changing it in DetailView you change same object.

Asperi
  • 228,894
  • 20
  • 464
  • 690
1

FetchedResults<MyEntity> entities does not conform to Binding or DynamicProperty. For the $ symbol to workout must conform to Binding.

You can make a FetchedResultsController in an ObservableObject to get the same functionality as an @FetchRequestand have the ability to pass the values in an EnvironmentObject or ObservedObject.

lorem ipsum
  • 21,175
  • 5
  • 24
  • 48