译自 Introducing List, your best friend
更多内容欢迎关注公众号「Swift花园」
在众多的 SwiftUI 视图中,List
是最值得你倚赖的类型之一。这并不是说你用它们的频率最高 —— 我确定 Text
或者 VStack
会在使用频次这一项夺冠 —— 而是因为它就像一匹负重的老马 —— 你需要时不时到回到它这里借助它的力气。这也不新鲜了,List
在 UIKit 中对应的是 UITableView
,它已经被广泛使用。
List
的工作是提供一个可以滚动显示数据的表格。实际上,它跟 Form
几乎一样,除了它是用来呈现数据而不是请求用户的输入。不要误会我的意思:你当然也会经常用到 Form
,不过它本质是一种特殊类型的 List
。
就像 Form
一样,你可以提供给 List
一组静态的视图,它们会被渲染成独立的行:
List {
Text("Hello World")
Text("Hello World")
Text("Hello World")
}
我们也可以使用 ForEach
来完成,以便基于数组或者范围动态创建视图:
List {
ForEach(0..<5) {
Text("Dynamic row \($0)")
}
}
你还可以混合静态和动态的行:
List {
Text("Static row 1")
Text("Static row 2")
ForEach(0..<5) {
Text("Dynamic row \($0)")
}
Text("Static row 3")
Text("Static row 4")
}
当然,结合 section ,我们可以让列表可读性更好:
List {
Section(header: Text("Section 1")) {
Text("Static row 1")
Text("Static row 2")
}
Section(header: Text("Section 2")) {
ForEach(0..<5) {
Text("Dynamic row \($0)")
}
}
Section(header: Text("Section 3")) {
Text("Static row 3")
Text("Static row 4")
}
}
可以把动态和静态内容放在一起的能力使得我们可以重建像设置 app 里的 Wi-Fi 界面 —— 一个可以启动 Wi-Fi 的开关,然后一组附近网络的动态列表,然后再来一些注入自动假如热点之类的静态单元。
你会留意这种列表跟我们之前遇到的不一样,但本质上你在 iOS 上看到的各种不同东西其实就是各种不同风格的表格视图。我们可以用listStyle()
modifier 把列表改造成跟设置一样的风格:
.listStyle(GroupedListStyle())
目前为止你能用在Form
的东西,跟 List
一模一样,即使是动态内容。但有一样只有 List
能做到而 Form
做不到的事情是,不用 ForEach
也能基于动态内容生成视图。
如果你的整个列表的内容都是基于动态的行,那么你可以简化写法:
List(0..<5) {
Text("Dynamic row \($0)")
}
这使得我们可以非常快地创建列表,基于它们很常用这一点这种小技巧会很有助益。
在接下来的项目中我们使用 List
的方式会略有不同,因为我们将通过遍历一个字符串数组的方式来创建列表。
当配合数组数据时,SwiftUI 是需要识别每个单独的行的,以便当我们移除某行时,它不需要重绘整个列表。 由此引入了 id
参数,它在 List
和 ForEach
里都可以工作 —— 它告诉 SwiftUI 的东西是什么让数组中的元素唯一化的标识。.
当你处理字符串数组或者数字数组时,唯一能让每个元素唯一的东西只有元素本身。举个例子,我们有数组 [2, 4, 6, 8, 10]
,那么每个数字自身就是它们的唯一标识符。毕竟,也没的东西了!
在列表中处理这类数据时,我们用 id: \.self
,就像这样:
struct ContentView: View {
let people = ["Finn", "Leia", "Luke", "Rey"]
var body: some View {
List(people, id: \.self) {
Text($0)
}
}
}
ForEach
里的用法一样:
List {
ForEach(people, id: \.self) {
Text($0)
}
}
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~