[SwiftUI 知识碎片] 介绍 List - 你的小伙伴

1,006 阅读2分钟
译自 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 参数,它在 ListForEach里都可以工作 —— 它告诉 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及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~