第56天 项目 11 第四部分
在跟着我完成一个项目几天后,现在该你走出舒适区,开始自己编写代码了。再次强调,这些挑战是我根据你目前所学的所有知识设定的,这意味着只要你用心去做,就完全有能力完成。
艾米·莫林(一位从社会工作者转型的作家)曾说过:“你越练习容忍不适,就越有信心接受新的挑战。”这就是所有这些挑战背后的目标:稍微推动你去尝试自己动手,去弄清楚什么方法可行——坦率地说,在找到正确解决方案之前,你可能会犯错几次。
把事情做对固然有价值,但犯错也同样有价值。拥抱这一点吧——学会容忍自己编写新代码时必然会伴随的不适感——这样你就能成为一名优秀的开发者。
今天,你应该完成第11个项目的总结章节,完成相关复习,然后攻克它的三个挑战。
- 书虫(Bookworm):总结
- 第11个项目复习:书虫(Bookworm)
在网上分享一些你学到的东西,或者你将来可能如何运用这些知识——你喜欢SwiftData吗?你渴望创建更多自定义用户界面组件吗?告诉大家吧——保持责任感!
书虫(Bookworm):总结
作者:Paul Hudson 2023年11月19日
恭喜你又完成了一个SwiftUI项目!有了SwiftData这样的技术支持,现在你有能力构建一些功能完善的应用程序了——这些应用不仅能与用户交互,而且最重要的是,能“记住”用户输入的内容。虽然我们对SwiftData的探索只是浅尝辄止,但它的能力远不止于此,而且我预计苹果公司在未来的更新中,会继续加强SwiftData与SwiftUI之间的联系。不过,下一个项目就会深入探讨SwiftData——还有很多内容等着我们去探索呢!
至于你学到的其他知识,现在你已经接触了更多SwiftUI的属性包装器,希望你能逐渐明白该如何选择以及何时使用它们。@Binding在构建自定义UI组件时特别有用,因为它能在视图之间共享数据,这一点非常实用。
最后还有一件事我想提醒你,这件事你可能根本没有注意到。当我们构建星级评分组件时,我们创建了一个像Button(按钮)和Slider(滑块)一样具有用户交互功能的控件。但是,我们并没有考虑它在辅助功能方面的表现,这是个问题:Button、Slider等控件在默认情况下就能很好地支持辅助功能,但一旦我们开始创建自己的组件,就需要亲自着手处理这方面的工作了。
构建对所有人都无障碍的应用程序,是每个人都需要认真对待的事情,这也是为什么我会在之后专门安排一个技术项目来讲解辅助功能——我们会回顾之前制作的项目,看看如何对它们进行改进。
不过,先把眼前的事做好——你还有新的复习内容和一些挑战要完成。祝你好运!
复习所学内容
任何人都能看完一个教程,但要记住所学的知识,就需要付出实际的努力。我的职责是确保你能从这些教程中收获尽可能多的知识,完成后面的练习题可以帮助你检验自己的学习成果。
挑战
学习编程最好的方法之一就是尽可能多地自己编写代码,所以这里有三种扩展这个应用程序的方式,帮助你确保完全理解其中的原理。
- 目前,用户可以选择不输入书籍的标题、作者或类型,这会给详情视图带来问题。请修复这个问题,你可以选择强制设置默认值、验证表单,或者为未知类型显示默认图片——选择哪种方式都可以。
- 修改
ContentView(内容视图),让评分为1星的书籍以某种方式突出显示,比如将书名显示为红色。 - 给Book(书籍)类添加一个新的“date”(日期)属性,将
Date.now(当前日期时间)赋值给它,然后在DetailView(详情视图)的某个位置将这个日期格式化后美观地显示出来。
【练习题】书虫(Bookworm)
问题1/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:
@Binding允许我们在两个地方共享同一个结构体。 - 选项2:
@Binding不能用于私有属性。
问题2/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:每个视图只能使用一次
@Environment。 - 选项2:可以使用关闭工作表(sheet)的代码来从
NavigationStack(导航栈)中弹出一个视图。
问题3/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:可以使用
font()修饰符来调整SF Symbols(苹果系统图标库)中图标的大小。 - 选项2:
SortDescriptor(排序描述符)始终按升序排序。
问题4/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:SwiftData内置在所有苹果设备中,包括Vision Pro(苹果混合现实头显)。
- 选项2:
@Binding和@Bindable的作用相同。
问题5/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:当用户可能会删除某些数据时,应该使用
.destructive(破坏性)按钮样式。 - 选项2:如果我们有一个名为
book的SwiftData模型对象,应该调用book.delete()来将其从模型上下文中删除。
问题6/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:创建模型上下文时,SwiftData会自动为我们创建一个模型容器。
- 选项2:
onDelete(perform:)不能直接附加到List(列表)视图上。
问题7/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:为
TextField(文本框)指定轴(axis)可以让它在用户输入时自动扩展。 - 选项2:使用SwiftData的获取请求(fetch request)时,必须始终指定排序字段。
问题8/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:不能将
onDelete(perform:)用于由SwiftData对象支持的视图。 - 选项2:可以创建一个临时的模型容器,用于SwiftUI预览。
问题9/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:SwiftData模型在Swift中是类(class)类型。
- 选项2:SwiftData最多可以存储1000个同类型的对象。
问题10/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:SwiftData模型对象可以自动被SwiftUI观察。
- 选项2:以工作表(sheet)形式呈现的视图会自动共享呈现它的视图的环境。
问题11/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:SwiftData类必须标记为
@Observable。 - 选项2:必须在模型上下文中创建SwiftData模型对象。
问题12/12:以下哪些表述是正确的?
提示:点击显示。
- 选项1:常量绑定(constant bindings)的值不能被用户修改。
- 选项2:为了避免数据丢失,必须始终记得保存模型上下文。