Reputation: 413
I have a list of bookmarks saved in Core Data. When i try to click on the edit button for a particular bookmark, only the values of the first bookmark on the list will fill up the textfields in the editing sheet no matter which bookmark i pick.
This is a macOS 10.15 app.
ContentView
@State private var showEditView = false
ForEach(vm.myBookmarks) { myBookmark in
Text(myBookmark.name)
Text(myBookmark.url)
Button {
showEditView = true
} label: {
Image("pencil")
}
.sheet(isPresented: $showEditView) {
EditBookmarkView(name: myBookmark.name, url: myBookmark.url, isVisible: $showEditView, bm: myBookmark)
}
}
EditBookmarkView
struct EditBookmarkView: View {
@Environment(\.presentationMode) var presentationMode
@Binding var isVisible: Bool
@ObservedObject var vm: EditBookmarkViewModel
let name: String
let url: String
var bm: MyBookmarkViewModel
init(name: String, url: String, isVisible: Binding<Bool>, bm: MyBookmarkViewModel) {
self.bm = bm
self.vm = EditBookmarkViewModel(bookmarkVM: bm)
_isVisible = isVisible
self.name = name
self.url = url
}
var body: some View {
TextField("Edit Name", text: $vm.name)
Spacer()
TextField("Edit url", text: $vm.url)
Button("Update") {
vm.save()
}
}
}
Upvotes: 2
Views: 621
Reputation: 88152
You create a sheet for each item in ForEach
, and only one sheet can be represented at a time. So showEditView
shows the sheet related to the first view in the hierarchy and it in turn captures the first item in your list.
Instead you can you use sheet
which accepts item binding: sheet is presented when the item is not nil
. You only need one such sheet, so add it to your list, not to each item.
When you finish editing, set selectedBookmark
to nil
to hide the sheet.
Full working example:
struct Bookmark: Identifiable {
let id: Int
}
struct ContentView: View {
@State private var selectedBookmark: Bookmark?
let items = (0..<10).map { Bookmark(id: $0) }
var body: some View {
ForEach(items) { myBookmark in
HStack {
Text(String(describing: myBookmark))
Button {
selectedBookmark = myBookmark
} label: {
Image(systemName: "pencil").foregroundColor(.red)
}
}
}
.sheet(item: $selectedBookmark) { selectedBookmark in
let _ = print(String(describing: selectedBookmark))
Text(String(describing: selectedBookmark))
}
}
}
Upvotes: 4