'Can’t pass data correctly to modal presentation using ForEach and CoreData in SwiftUI

Im trying to pass data of some object from list of objects to modal sheet, fetching data from CoreData.

The problem is that no matter what object I click on in the list, only the data form last added object appears in the details view.

The same goes for deleting the object - no matter what object I'm trying to delete, the last one is deleted all the time.

Problem disappears using NavigationLink, but it is not suitable for me.

Here is my code:

import SwiftUI

struct CarScrollView: View {

    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Cars.entity(), sortDescriptors: []) var cars: FetchedResults<Cars>

    @State var showDetails = false

    var body: some View {
        VStack {
            ScrollView (.vertical, showsIndicators: false) {
                ForEach (cars, id: \.self) { car in

                    Text("\(car.text!)")
                        .onTapGesture {
                            self.showDetails.toggle()
                    }
                    .sheet(isPresented: self.$showDetails) { CarDetail(id: car.id, text: car.text)
                    }
                }
            }
        }
    }
}


Solution 1:[1]

There should be only one sheet in view stack, so just move it out of ForEach, like below

struct CarScrollView: View {

    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Cars.entity(), sortDescriptors: []) var cars: FetchedResults<Cars>

    @State private var selectedCar: Car? = nil

    var body: some View {
        VStack {
            ScrollView (.vertical, showsIndicators: false) {
                ForEach (cars, id: \.self) { car in

                    Text("\(car.text!)")
                        .onTapGesture {
                            self.selectedCar = car
                    }
                }
            }
        }
        .sheet(item: self.$selectedCar) { car in
             CarDetail(id: car.id, text: car.text)
        }

    }
}

backup

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1