首页 > 解决方案 > SwiftUI 绑定到 foreach 中的核心数据对象

问题描述

我无法将核心数据对象中的 bookName 绑定到 ForEach 循环内的 TextField。我怎样才能让这个绑定工作?我希望 bookName 值在更改时保存到 Core Data。

我收到一条错误消息:在范围内找不到 $book。

extension Book: Identifiable {
                @nonobjc public class func fetchRequest() -> NSFetchRequest<Book> {
                    return NSFetchRequest<Book>(entityName: "Book")
                }
                
                @NSManaged public var id: UUID?
                @NSManaged public var bookName: String?
                
                var wrappedBookName: String {
                    bookName ?? ""
                }
           }    
            
    struct BookListView: View {
            @FetchRequest(entity: Book.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Book.rankNumber, ascending: false)]) var books: FetchedResults<Book>
                
                 var body: some View {
                    ForEach(books) { book in
                       TextField("Book Name", text: $book.bookName)  //Error: cannot find $book in scope
                    }
                 }
    }

标签: core-dataswiftuicombine

解决方案


我喜欢使用 SwiftUI 的 CoreData。它的工作原理就是这么简单。只需使用ObservedObjectof Book 创建一个新的编辑视图。

struct EditView : View {
    @ObservedObject var book: Book
    
    init(book: Book) {
        self.book = book
    }
    
    var body : some View {
        TextField("Name", text: $book.bookName)
    }
}

就是这样。然后你可以$book.bookName作为绑定发送到字符串。

但是,请确保!您已在 CoreData 中将 bookName 声明为非可选值。TextField 需要 a Binding<String>,而不是 aBinding<String?>

在您的 ForEach 中使用该 EditView,您就可以开始了:

ForEach(books) { book in
    EditView(book: book)

推荐阅读