SwiftUI基础——构建列表和导航
Swift UI 基础
今天是 WWDC20 的第二天了,所以继续来学习 Apple 的 app 开发。😜
翻译自 SwiftUI 的官方教程:Learn to Make Apps with SwiftUI
这篇文章是 Apple 给的 SwiftUI 官方教程的一部分,我自己阅读学习的时候顺便翻译的。
构建列表和导航
原文链接:https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation
在我们已经完成了基本的地标细节视图后,现在,我们需要提供给用户一种方式,来查看完整的地标列表,并可以查看每一个地标的细节。
我们将构建可以展示任意地标信息的视图,还有动态生成一个滚动列表,用户可以点击列表里的项目来查看对应地标的细节信息。为了微调用户界面,我们将使用 Xcode 的画布在不同的设备尺寸下渲染多个预览。
载项目文件,跟着下面的步骤开始构建工程吧:
预计时间:35分钟
§ 1 认识样本数据(Sample Data)
在之前的教程中,我们把信息用硬编码(hard-coded)写死到了我们的自定义视图中。现在,我们将要学习如何让视图显示我们传进去的指定信息。
首先,下载打开起步项目文件,然后自己熟悉一下样本数据吧。
Step 1. 在项目导航(Project navigator)中选择 Models > Landmark.swift
。
Landmark.swift
declares a Landmark
structure that stores all of the landmark information the app needs to display, and imports an array of landmark data from landmarkData.json
.
Landmark.swift
声明了一个 Landmark
结构体,用来储存我们的 app 需要显示的所有地标信息(这些信息是从 landmarkData.json
读取出来的)。
1 | // Landmark.swift |
Step 2. 在项目导航中,选择 Resources > landmarkData.json
。
1 | [ |
在接下来的步骤中,我们都将使用这个样本数据文件。
Step 3. 注意,在 创建并组合视图 里我们写的 ContentView 现在重命名成了 LandmarkDetail
。
在接下来的教程中,我们还有构建更多的其他视图。
1 | // LandmarkDetail.swift |
预览效果是这样的:
§ 2 创建行视图(Row View)
在本教程中,我们将构建的第一个视图是一个用于显示每个地标详细信息的行。这个行视图将它所显示的地标的信息存储在一个属性中,因此一个这种视图是可以显示任何地标的。之后,我们将把多个这种行组合成一个地标列表。
Step 1. 创建一个新的 SwiftUI View,文件命名为 LandmarkRow.swift
。
Step 2. 如果预览没有显示,则通过 Editor > Canvas 打开画布,然后点 Resume。
Step 3. 给 LandmarkRow
添加一个 landmark 储存属性。
1 | // LandmarkRow.swift |
当你添加 landmark 属性时,预览会停止工作,因为LandmarkRow类型在初始化时需要一个 Landmark 实例。
为了修复预览,我们要修改一下预览提供器(PreviewProvider)。
Step 4. 在 LandmarkRow_Previews 的 previews 静态属性中,给 LandmarkRow 的初始化器中添加 landmark 参数,指定 landmarkData 数组的第一个元素。
现在,预览就可以工作了,显示出了文本 “Hello World”。
修复了这个问题之后,就可以开始构建行的视图了。
Step 5. 把现有的文本视图嵌入到一个 HStack 里。
Step 6. 把文本视图的内容改成 landmark
属性的 name
。
Step 7. 通过在文本视图前添加图像,在文本视图后添加间隔符来完成行。
这一节里我们完成的主要代码是LandmarkRow.swift
:
1 | import SwiftUI |
也可以在 Playground 里完成这个,但稍微有点麻烦。
新建一个 Playground,打开左侧的 Navigater,展开可以看到 Resources 文件夹,把 Apple 给的那个项目文件中的 Resources 里面的东西(一个 json文件,还有一堆图片文件)
§ 3 自定义行预览
Xcode 的画布可以自动识别并显示当前编辑器中实现了 PreviewProvider 协议的任何类型。预览提供器(preview provider)会返回一个或多个视图,并带有配置大小和设备的选项。
你可以自定义从预览提供器返回的内容,以准确地呈现对工作最有帮助的预览。
Step 1. 在LandmarkRow_Previews中,把 landmark 参数改为 landmarkData 数组中的第二个元素。
修改完代码,预览会立即改变,显示第二个样本地标,而不再是第一个。
Step 2. 使用 previewLayout(_:)
修饰器来把预览设置成近似一个行的尺寸大小。
我们可以使用一个 Group 来从一个 preview provider 返回多个预览。
Step 3. 将现在 previews 返回的 LandmarkRow 包裹在一个 Group 中,并将第一行再次添加回来。
Group 是对视图内容进行分组的容器。Xcode 在画布中以单独的预览来呈现 Group 的子视图。
Step 4. 为了简化代码,将 previewLayout(_:)
的调用移到组的子声明的外面。
视图的孩子 (Children) 会继承视图的上下文设置,例如预览配置。
我们在预览提供器(PreviewProvider)中写的代码只会改变画布(canvas)中显示的预览内容,不会影响视图本身。
§ 4 创建地标列表(the List of Landmarks)
使用 SwiftUI 的 List
类型,可以显示一个平台特定(platform-specific)的视图列表。列表中的元素可以是静态的,比如到目前为止你创建的那种 stack 的子视图,也可以是动态生成的。我们甚至可以在 List 里混合静态和动态生成的视图。
Step 1. 创建一个新的 SwiftUI View,命名为 LandmarkList.swift
。
Step 2. 用一个 List 替换默认的 Text 视图,并提供 LandmarkRow 实例,将前两个地标作为列表的子节点。
预览显示两个 LandmarkRow 以适合 iOS 的列表样式呈现出来了。