第19天 挑战日
今天你将迎来第一个挑战日,在这一天,你需要利用迄今为止所学的知识,从零开始构建一个全新的应用程序。这可能会让你感到意外,因为你可能会觉得自己到目前为止学到的东西还不多。不过,让我来解释一下……
《100 天 SwiftUI 学习计划》是我编写的第二个 “100 天系列” 课程。虽然我知道最初的《100 天 Swift 学习计划》非常受欢迎,也帮助了很多人,但事后我明确意识到:“如果让我重新做一遍,有些地方我会做出改变……”
其中一个改变是在最初的 Swift 学习阶段增加更多虚拟交流环节,帮助大家更好地掌握那些基础知识。而第二个改变,就是你今天将要面对的:我希望能让你更快地开始独立编写自己的项目。
在最初的《100 天 Swift 学习计划》中,大家先完成第一个项目,接着是第二个、第三个,直到这时才会被要求从零开始编写自己的应用。虽然这种模式也能起到一定效果,但回想起来,我发现不先巩固基础知识就直接进入第二个、第三个项目,并不是最理想的方式。
于是就有了今天的安排:你的第一个挑战日,你需要从零开始构建一个完整的应用程序。别担心:这个项目是根据你目前所学的内容专门挑选的,所以你需要掌握的所有知识,在第一个项目中都已经学过了。
你的挑战任务
你需要构建一个处理单位换算的应用程序:用户选择输入单位和输出单位,然后输入一个数值,就能看到换算后的结果。
具体选择哪些单位由你决定,你可以从以下类别中挑选一种:
- 温度换算:用户可选择摄氏度、华氏度或开尔文。
- 长度换算:用户可选择米、千米、英尺、码或英里。
- 时间换算:用户可选择秒、分钟、小时或天。
- 体积换算:用户可选择毫升、升、杯、品脱或加仑。
以长度换算为例,你的应用可能包含以下组件:
- 一个分段控制器(segmented control),用于选择输入单位(米、千米、英尺、码或英里)。
- 第二个分段控制器,用于选择输出单位(米、千米、英尺、码或英里)。
- 一个文本框(text field),供用户输入数值。
- 一个文本视图(text view),用于显示换算结果。
例如,如果用户选择输入单位为 “米”、输出单位为 “英尺”,然后输入 10,那么输出结果应该显示 32.81。
构建这个应用所需的知识,你几乎已经全部掌握了。事实上,如果你追求简单的解决方案(我也希望你这么做),唯一可能遇到的 “新知识” 就是文本框需要使用不同的format选项 —— 因为.currency(货币格式)和.percent(百分比格式)在这里并不适用,你应该选择.number(数字格式),它适合标准的数值输入场景。
提示建议
完成这个项目所需的知识你都已经具备了,但如果遇到问题,以下这些提示或许能帮到你:
首先,也是最重要的一点:保持简单!在未来的职业生涯中,你会有足够多的时间去研究巧妙的代码架构等复杂内容,但在这个初始挑战中,我希望你选择最简单的解决方案。
其次,所有单位换算本质上都是简单的数学运算,但你不必编写从 “每个输入单位” 到 “其他所有输出单位” 的换算逻辑。更好的思路是:先将用户输入的数值换算成一个统一的 “基准单位”,然后再从基准单位换算成用户选择的输出单位。
比如,与其分别编写 “升转毫升”“升转杯”“升转品脱” 等一系列换算代码,不如先将用户输入的数值统一换算成 “毫升”(最小公约数单位),然后再从毫升换算成用户需要的任何输出单位。
第三,由于这里涉及三个用户相关的值 —— 用户输入的数字、输入单位、输出单位 —— 你需要用三个@State属性来存储它们。你还需要一个TextField(文本框)、两个选择器(picker)和一个文本视图(用于显示输出结果),基本上就这些组件了。你可以根据需要将表单分成不同的分区(section),但这并不是必需的。
第四,存储换算单位最简单的方式是使用一个简单的字符串数组,然后通过ForEach(units, id: \.self)这类代码来遍历数组(生成选择器选项)。
最后,如果你想让显示的输出数值更美观一些,可以尝试调用数值的.formatted()方法 —— 例如someDouble.formatted()。这会让 iOS 自动对数值进行格式化处理,添加千位分隔符,并去除不必要的小数位,避免显示冗余信息。
现在就开始动手吧!如果需要回顾 “WeSplit” 项目(之前的示例项目),完全没问题 —— 这很正常,也是学习过程的一部分。
祝你好运!你一定能做到的。完成后,记得告诉其他人:你又构建了一个 SwiftUI 应用,而且这个应用完全是由你自主设计的。
你应该为自己取得的成就感到骄傲。
提示:尽管你完全可以通过简单的算术运算完成这个项目,但你可能会感兴趣的是,苹果其实为我们提供了专门用于单位换算的功能 —— 如果你好奇,可以阅读下面的文章。不过需要重申的是,完成这个项目并不需要使用该功能:例如,你只需将输入乘以 2.11338 就可以将升转换为品脱。
【扩展阅读】如何使用 Unit 和 Measurement 进行单位换算
Swift 版本:5.10
作者:Paul Hudson 日期:2019 年 5 月 28 日
iOS 10 引入了一套新的系统,可用于计算距离、长度、面积、体积、时长等多种物理量的测量值。我们从简单的例子开始讲解。如果你身高 6 英尺,可以像这样创建一个 Measurement 实例:
let heightFeet = Measurement(value: 6, unit: UnitLength.feet)需要注意的是,Swift 无法将 .feet 自动推断为 UnitLength.feet,因为后面你会发现,Unit 的子类数量非常多。
创建好测量值实例后,你可以按如下方式将其换算为其他单位:
let heightInches = heightFeet.converted(to: UnitLength.inches)
let heightSensible = heightFeet.converted(to: UnitLength.meters)在输出结果中,你应该会看到 “72.0 in”(72.0 英寸)和 “1.8288 m”(1.8288 米),这表明单位换算过程已成功执行。
与所有单位子类一样,UnitLength(长度单位类)涵盖了从传统单位到现代单位的广泛范围。例如,你可以将英尺换算为天文单位(1 天文单位约等于地球与太阳的平均距离,即约 1.5 亿千米):
let heightAUs = heightFeet.converted(to: UnitLength.astronomicalUnits)掌握一种单位的用法后,其他单位的使用方式完全相同。以下是更多示例,帮助你快速上手:
// 将度(角度单位)换算为弧度
let degrees = Measurement(value: 180, unit: UnitAngle.degrees)
let radians = degrees.converted(to: .radians)
// 将平方米换算为平方厘米
let squareMeters = Measurement(value: 4, unit: UnitArea.squareMeters)
let squareCentimeters = squareMeters.converted(to: .squareCentimeters)
// 将蒲式耳(体积单位)换算为英制茶匙
let bushels = Measurement(value: 6, unit: UnitVolume.bushels)
let teaspoons = bushels.converted(to: .imperialTeaspoons)说实话,我完全不知道蒲式耳与英制茶匙之间的换算比例是多少,但能有这个换算选项总归是好的!