You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中数组内指定结构体的删除与编辑问题

解决方案:修复删除逻辑与完善编辑保存功能

一、修复ContentView中的删除操作

你之前的删除代码会清空整个数组,是因为bookData.contains(bookDetail)的判断逻辑有问题——对于数组里的每一个元素,这个条件都会返回true(只要数组里存在该元素),所以removeAll会删掉所有内容。

正确的做法是利用Book的唯一标识符(也就是你在NewBook里用的UUID生成的id)来精准匹配要删除的元素。修改上下文菜单的按钮动作如下:

Button(action: {
    // 通过id匹配,删除指定的书籍
    bookData.removeAll { $0.id == bookDetail.id }
    // 保存修改后的数组到JSON文件
    writeJSON(bookData)
}) {
    Label("Delete", systemImage: "trash")
}

二、完善EditBook的编辑与保存逻辑

你的EditBook目前有两个问题:一是没有初始化编辑框的默认值为当前书籍的信息,二是点击"Update book"按钮时没有执行更新和保存操作。我们可以通过初始化方法设置默认值,并在按钮动作中找到数组对应的元素进行修改。

修改后的EditBook代码:

struct EditBook: View {
    @Binding var bookData: [Book]
    @State private var name: String
    @State private var author: String
    @State private var page: String
    @State private var total: String
    let book: Book
    // 添加环境变量用于返回上一页
    @Environment(\.presentationMode) var presentationMode

    // 初始化时将传入书籍的信息赋值给编辑状态变量
    init(bookData: Binding<[Book]>, book: Book) {
        self._bookData = bookData
        self.book = book
        self._name = State(initialValue: book.name)
        self._author = State(initialValue: book.author)
        self._page = State(initialValue: book.page)
        self._total = State(initialValue: book.total)
    }

    var body: some View {
        Form{
            Section(header: Text("Change the details of the book")){
                HStack{
                    Text("Name:")
                    // 占位符留空,因为我们已经初始化了当前书籍的名称
                    TextField("", text: $name)
                }
                HStack{
                    Text("Author:")
                    TextField("", text: $author)
                }
                HStack{
                    Text("Page number:")
                    TextField("", text: $page)
                        .keyboardType(.numberPad)
                }
                HStack{
                    Text("Number of pages:")
                    TextField("", text: $total)
                        .keyboardType(.numberPad)
                }
            }
            Section{
                HStack{
                    Spacer()
                    Button(action: {
                        // 通过id找到数组中对应的书籍索引
                        if let index = bookData.firstIndex(where: { $0.id == book.id }) {
                            // 更新该位置书籍的属性
                            bookData[index].name = name
                            bookData[index].author = author
                            bookData[index].page = page
                            bookData[index].total = total
                            // 或者直接替换整个元素(如果需要修改image等其他属性时更方便)
                            // bookData[index] = Book(id: book.id, name: name, author: author, page: page, total: total, image: book.image)
                            
                            // 保存修改后的数组到JSON文件
                            writeJSON(bookData)
                            // 返回上一页
                            presentationMode.wrappedValue.dismiss()
                        }
                    }) {
                        Text("Update book")
                    }
                    Spacer()
                }
            }
        }
        .navigationTitle("Edit Book")
    }
}

三、确保Book结构体符合要求

为了让上述逻辑正常工作,你的Book结构体需要满足两个条件:

  1. 遵循Identifiable协议(这样ForEach和firstIndex才能通过id正确识别元素)
  2. 可编辑的属性必须用var声明(而不是let)

示例Book结构体:

struct Book: Identifiable, Codable {
    let id: UUID
    var name: String
    var author: String
    var page: String
    var total: String
    var image: String
}

这样修改后,删除指定书籍和编辑保存的功能就都能正常工作了!

内容的提问来源于stack exchange,提问作者Arnav Motwani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:22:49