[SwiftUI 100天] Bookworm-part9 删除 Core Data 对象
2020/4/27 23:04:02
本文主要是介绍[SwiftUI 100天] Bookworm-part9 删除 Core Data 对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
译自 www.hackingwithswift.com/books/ios-s…
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀
从一个 Core Data fetech request 中删除对象
我们已经使用了@FetchRequest
来拉取 Core Data 对象到 SwiftUI 的List
,再增加少量工作,我们就能启用轻扫删除和编辑/完成按钮。
就像常规的数据数组一样,大部分的工作是通过附加一个onDelete(perform:)
modifier 给ForEach
来实现的,不过相对于从数组中移除项,我们需要从 fetch 请求中找到请求的对象,然后对其调用我们的 managed object context 的delete()
方法。一旦目标对象都删除完成,我们需要触发 context 的保存。如果不这么做,变更不会被实际写入磁盘。
把下面这个方法添加到ContentView
:
func deleteBooks(at offsets: IndexSet) { for offset in offsets { // find this book in our fetch request let book = books[offset] // delete it from the context moc.delete(book) } // save the context try? moc.save() }复制代码
注意,onDelete(perform:)
modifier 是附着在ForEach
而不是List
。
添加下面这个 modifier:
.onDelete(perform: deleteBooks)复制代码
这样我们就获得了轻扫删除功能,我们可以更进一步,添加一个编辑/完成按钮。找到ContentView
的navigationBarItems()
modifier ,修改成下面这样:
.navigationBarItems(leading: EditButton(), trailing: Button(action: {复制代码
这样就完成了ContentView
,再次尝试运行应用 —— 你应该可以自由地添加和删除图书了,删除操作是通过轻扫手势或者编辑按钮来触发。
译自 www.hackingwithswift.com/books/ios-s…
用 alert 显示 NavigationLink
你已经了解如何使用NavigationLink
跳转新的一屏,这个新视图可以某个自定义的视图或者 SwiftUI 的内置类型,比如Text
或者Image
。因为我们是处于一个NavigationView
,iOS 自动提供了一个 “Back” 按钮,让用户可以返回之前一屏,它们也可以从屏幕的左边缘轻扫返回。不过,有的时候通过编程返回也是有用的。
为了演示这一点,我们要给我们的应用添加最后一个特性:删除用户正在看的书。做这个操作时,我们需要显示一个警告框,提示用户是否真的想要删除该书,得到肯定之后再从当前 managed object context 删除该书。一旦这个动作完成,停留在当前界面就没有意义了,因为关联的书已经不存在了。我们需要弹出当前视图 —— 将其从NavigationView
栈顶移除,并且返回之前一屏。
首先,我们需要三个新的属性,放在DetailView
结构体中:一个持有 Core Data managed object context (这样我们才能删除东西),一个持有 presentation mode(这样我们才能从导航栈中弹出视图),一个控制我们是否要显示确认警告的状态。
把下面三个属性添加到DetailView
:
@Environment(\.managedObjectContext) var moc @Environment(\.presentationMode) var presentationMode @State private var showingDeleteAlert = false复制代码
第二步是写一个删除当前图书的方法,然后 dismiss 当前视图。至于这个视图是通过 navigation link 而不是 sheet 显示的这一点区别,我们仍然可以使用相同的presentationMode.wrappedValue.dismiss()
代码。
把下面这个方法添加到DetailView
:
func deleteBook() { moc.delete(book) // uncomment this line if you want to make the deletion permanent // try? self.moc.save() presentationMode.wrappedValue.dismiss() }复制代码
第三步是添加一个alert()
modifier,关注showingDeleteAlert
,内部展示一个Alert
视图,询问用户确认动作。目前为止我们用过有一个 dimiss 按钮的简单 alert,这一回我们需要两个按钮:一个按钮删除图书,另一个取消。
SwiftUI 为这个用途提供两个专门的按钮:.destructive
接收标题和 action 闭包,显示为红色,以便警告用户该操作将删除数据,.cancel()
则会导致 alert 被 dismisse。 Apple 对于我们应该给 alert 文本取标签提供了明确的指引,让我在这里重申一下:如果只是简单如“我明白”,那么“OK”就是可以的,但假如你希望用户做出选择,那你应该避免像“Yes” 和 “No” 这样的标题,而应该使用像 “Ignore”,“Reply” 和 “Confirm” 这样的动词。
在这个案例中,我们将采用 “Delete”作为 destructive 按钮的标题,然后是一个.cancel()
按钮,以便用户可以退出删除操作。把下面这个 modifier 添加到DetailView
的GeometryReader
:
.alert(isPresented: $showingDeleteAlert) { Alert(title: Text("Delete book"), message: Text("Are you sure?"), primaryButton: .destructive(Text("Delete")) { self.deleteBook() }, secondaryButton: .cancel() ) }复制代码
最后一步是添加一个导航栏按钮,以启动删除过程 —— 它只做一件事,反转showingDeleteAlert
布尔型,因为alert()
modifier 已经在监控它。把下面这个 modifier 也添加到DetailView
的GeometryReader
:
.navigationBarItems(trailing: Button(action: { self.showingDeleteAlert = true }) { Image(systemName: "trash") })复制代码
现在你可以在ContentView
里使用轻扫或者编辑按钮来删除图书,或者在DetailView
视图中点击专门的删除按钮完成同样的目标 —— 它会删除该书,更新ContentView
列表,然后自动关闭当前细节视图。
又一个应用完成了 —— 干得漂亮!
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~
这篇关于[SwiftUI 100天] Bookworm-part9 删除 Core Data 对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-10-05Swift语法学习--基于协议进行网络请求
- 2022-08-17Apple开发_Swift语言地标注释
- 2022-07-24Swift 初见
- 2022-05-22SwiftUI App 支持多语种 All In One
- 2022-05-10SwiftUI 组件参数简写 All In One
- 2022-04-14SwiftUI 学习笔记
- 2022-02-23Swift 文件夹和文件操作
- 2022-02-17Swift中使用KVO
- 2022-02-08Swift 汇编 String array
- 2022-01-30SwiftUI3.0页面反向传值