The problem is that you have attached the .sheet modifier to the view inside of the ForEach, which means that every view has that sheet that presents its own version of EditView. Also the .contextMenu modifier should be attached to each view in the ForEach so it has access to the object that has been selected.
I have changed your code so that this should (theoretically) work.
// When the button in the context menu is tapped, the index of the corresponding object is stored in the selectedObjectIndex variable.
// This triggers the sheet to appear with an unwrapped selectedObjectIndex which is used to get the object that is passed to the EditView.
struct ContentView: View {
@State private var objectList = [Object(title: "First", string: "Editor"), Object(title: "Second", string: "Addition"), Object(title: "Third", string: "Twelve")]
@State private var selectedObjectIndex: Int?
var body: some View {
NavigationView{
List{
Section("Objects"){
ForEach(objectList) { object in
NavigationLink(destination: ObjectView(obj: object)){
Text(object.title)
}
.contextMenu{ // move inside ForEach
Button(action: {
self.selectedObjectIndex = objectList.firstIndex(of: object)
}){
Text("Edit Item")
}
}
}
}
.sheet(item: $selectedObjectIndex) { index in // move outside ForEach and use item initialiser
EditView(obj: objectList[index])
}
}
.listStyle(InsetGroupedListStyle())
.cornerRadius(10)
.navigationBarTitle("My List")
}
}
}