SwiftUI:只能编辑 ForEach 列表中的第一项

SwiftUI: Can only Edit the first item in a ForEach List

我在 Core Data 中保存了一个书签列表。当我尝试单击特定书签的编辑按钮时,无论我选择哪个书签,只有列表中第一个书签的值会填满编辑中的文本字段sheet。

这是 macOS 10.15 应用程序。

内容视图

@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)
                            }
                        }

编辑书签视图

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()
            
        }
           
        
      }

   }

您为 ForEach 中的每个项目创建一个 sheet,并且一次只能表示一个 sheet。因此 showEditView 显示与层次结构中第一个视图相关的 sheet,它又捕获列表中的第一个项目。

您可以使用接受项目绑定的 sheet:当项目不是 nil 时显示 sheet。您只需要一个这样的 sheet,因此将其添加到您的列表中,而不是每个项目中。

完成编辑后,将 selectedBookmark 设置为 nil 以隐藏 sheet。

完整的工作示例:

struct Bookmark: Identifiable {
    let id: Int
}

struct ContentView: View {

    @State private var selectedBookmark: Bookmark?
    let items = (0..<10).map { Bookmark(id: [=10=]) }

    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))
        }
    }
}