【问题标题】:Deleting and editing specific structs in an array删除和编辑数组中的特定结构
【发布时间】:2020-10-19 08:00:21
【问题描述】:

我的内容视图是一个由解码的 json 数组填充的表单,如下所示:

struct ContentView: View {
    
    @State var bookData: [Book] = load("list")
    @State private var selectedBook: Book? = nil
    @State private var active = false
    
    var body: some View {
        
        NavigationView {
                Form {
                    ForEach(bookData){ bookDetail in
                        BookView(book: bookDetail)
                            .background(
                                NavigationLink(destination: EditBook(bookData: $bookData, book: bookDetail), tag: bookDetail, selection: $selectedBook) {
                                           EmptyView()
                                        }
                                    )
                            .contextMenu{
                                Button(action: {
                                    
                                    //delete action here

                                }) {
                                    Label("Delete", systemImage: "trash")

                                }
                            }
                    }
                }
                .navigationBarTitle("Books")
                .navigationBarItems(trailing: NavigationLink(destination: NewBook(bookData: $bookData)){Image(systemName: "plus.circle").font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)})
        }
    }

}

我的应用程序现在的工作方式是 NewBook 和 Edit 图书视图对我的 bookData 数组有一个 binder 属性。要将新书添加到数组中,NewBook 视图只需将 bookData 附加到另一个结构并使用 writeJSON(bookData) 对其进行编码。同样,在内容视图中,我想使用上下文菜单删除一个元素并重新编码已编辑的数组。对于 editBook 视图,我想编辑一个结构并使用 writeJSON 对其进行编码。

这是我的 editBook 视图:

struct EditBook: View {

    @Binding var bookData: [Book]
    @State private var name = ""
    @State private var author = ""
    @State private var page = ""
    @State private var total = ""
    
    var book: Book
    
    var body: some View {
            Form{
                Section(header: Text("Change the details of the book")){
                    
                    HStack{
                        Text("Name:")
                        TextField(book.name, text: $name)
                    }
                    
                    HStack{
                        Text("Author:")
                        TextField(book.author, text: $author)
                    }
                    
                    HStack{
                        Text("Page number:")
                        TextField(book.page, text: $page)
                            .keyboardType(.numberPad)
                    }
                    
                    HStack{
                        Text("Number of pages:")
                        TextField(book.total, text: $total)
                            .keyboardType(.numberPad)
                    }
                }
                Section{
                    HStack{
                        Spacer()
                        Button(action: {
                            
                        }) {
                            Text("Update book")
                        }
                        Spacer()
                    }
                }
            }
            .navigationTitle("Edit Book")
    }
}

这是有效的 NewBook 视图(供参考)

struct NewBook: View {
    @Binding var bookData: [Book]
    @State private var name = ""
    @State private var author = ""
    @State private var page = ""
    @State private var total = ""
    
    var body: some View {
            Form{
                Section(header: Text("Enter the details of the book")){
                    TextField("Title", text: $name)
                    TextField("Author", text: $author)
                    TextField("Current page number", text: $page)
                        .keyboardType(.numberPad)
                    TextField("Total number of pages", text: $total)
                        .keyboardType(.numberPad)
                }
                
                Section{
                    HStack{
                        Spacer()
                        Button(action: {
                            bookData.append(Book(id: UUID(), name: name, author: author, page: page, total: total, image: "string"))
                            writeJSON(bookData)
                        }) {
                            Text("Add book")
                        }
                        Spacer()
                    }
                }
            }
            .navigationTitle("New Book")
    }
}

我尝试在内容视图中使用bookData.removeAll(where: {bookData.contains(bookDetail)}),但删除了所有内容。

【问题讨论】:

  • 我将从重构以使用模型对象开始。该对象应包含您的书籍数组以及处理序列化/反序列化。你可以让你的书符合identifiable(或者至少有一个唯一的标识符),这样你的模型就可以轻松识别正在编辑的书
  • @Paulw11 这本书的结构已经符合可识别的 uuid,我不明白为什么我应该将数组变成一个结构(我能想到的唯一原因是结构包含我的编码和解码功能)
  • 没错。编码和解码等业务逻辑属于你的模型,而不是你的视图。事实上,我可能会把它变成一个类而不是一个结构。
  • @Paulw11 会提高性能,有什么好处?
  • 这与性能无关。这是关于建筑的。通过使用作为类的模型对象,您可以获得可变性、引用语义和 ObservableObject 支持。在 SwiftUI 中,您的视图中应该几乎没有程序代码

标签: ios arrays swift swiftui


【解决方案1】:

经过反复试验,这对我有用。

要删除一个元素,我将这段代码放在内容视图的按钮中

bookData.removeAll(where: { $0.id == bookDetail.id })
writeJSON(bookData)

为了编辑数据,我这样做了

let id = book.id
bookData.removeAll(where: { $0.id == book.id })
let temp = Book(id: id, name: name, author: author, page: page, total: total, image: "Image")
bookData.insert(temp, at: 0)
writeJSON(bookData)

注意 id 如何在编辑时保持不变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多