0

在我使用 SwiftUI 作为界面的应用程序中,我有一个执行操作的按钮:

func getBooksCountNumber() -> Int {
    var countResult = 0
    let booksFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Book")
    
    do {
        let booksFetch = try self.persistentContainer.viewContext.fetch(booksFetch) as! [Book]
        countResult = booksFetch.count
        print("countResult is \(countResult)")
    } catch {
        fatalError("Failed to fetch: \(error)")
    }

    return countResult
}

当我删除应用程序中的行时,我使用moc.delete(book)try? moc.save(). 我看到删除的行不见了,使用 icloud.developer.apple.com 上的界面。例如——如果我从 3 条记录中删除 1 条,我仍然得到 3 条countResult而不是 2 条。感谢任何帮助。

4

1 回答 1

0

SwiftUI 依靠数据失效来强制View重新加载。

因此,您需要考虑如何使View代码依赖于数据的变化,countResult例如(例如)。

如果您使用的是 SwiftUI,我建议您考虑使用@FetchRequest属性包装器来获取您的数据集...

@FetchRequest(entity: Book.entity(),
              sortDescriptors: []
) var books: FetchedResults<Book>

注意:该sortDescriptors:参数是必需的,因此如果您不想对 排序FetchedResults,则包含一个空数组[]

然后使用与该包装器关联的属性将数据馈送到您的视图中......

struct YourView: View {
    // @FetchRequest here
    var body: some View {
        ...
        Text("Book count = \(books.count)")
        ...
    }
}

这样,您甚至不需要按下按钮来确定计数,因为Text每次在您的Book实体中添加或删除一本书时,视图都会更新。

用 SwiftUI 的方式写,随着数据的变化,Text视图组件会失效,视图struct会被强制重绘。

如果您想将按钮保留在您的视图中,您可以执行类似的操作...

    var body: some View {
        ...
        Button(action: {
            // code to perform your action here...
        }) {
            Text("You have \(books.count) books")
        }
        ...
    }

其中按钮的标签包括书籍的数量(并且按钮执行一些其他操作)。

于 2020-09-20T13:47:47.607 回答