SwiftUI控件之 List(二)

创建 List

在之前的List 使用中,我们是直接使用ForEach 循环遍历一个数组来实现的,在遍历的时候我们把self 作为List中必须的ID。接下来,我们通过自定义一个数据对象同时让它实现Identifiable

1
2
3
4
struct Ocean: Identifiable {
let name: String
let id: String = UUID().uuidString
}

在上面的代码中,我们自定义了一个结构体类型的对象Ocean ,同时让它实现了Identifiable 协议。在实现这个协议之后,它需要结构体的有一个名为id的成员属性,然后这个属性的值我们直接通过UUID().uuisString 创建一个字符串类型的值给它,这样可以实现之后创建的每一个Ocean 实例对象都有一个唯一ID,便于我们在List 遍历时使用。

同样地,使用数组的方式创建一些数据源。

1
2
3
4
5
6
7
private var oceans = [
Ocean(name: "Pacific"),
Ocean(name: "Atlantic"),
Ocean(name: "Indian"),
Ocean(name: "Southern"),
Ocean(name: "Arctic")
]

使用ListForEach创建一个List

1
2
3
4
5
List {
ForEach(oceans) { ocean in
Text(ocean.name)
}
}

注意:在上面的代码中,由于ForEach遍历的对象实现了Identifiable协议,所以我们就不再需要去单独设置id

或者可以直接讲数据源给到List来创建:

1
2
3
List(oceans) { ocean in
Text(ocean.name)
}

上面的代码也可以通过语法进行简写:

1
2
3
List(oceans) {
Text($0.name)
}

简写前和简写后的效果是一样的,简写代码中的$0表示遍历的第一个参数,还可以有类似于$1$2 …等这样的形式。

List 中的多选

首先将List嵌套到NavigationStack中实现一个带顶部导航栏的样式:

1
2
3
4
5
6
NavigationStack {
List(oceans) {
Text($0.name)
}
.navigationTitle("Oceans") // 导航栏的标题
}

同时,通过toolBar添加一个EditButton 按钮:

1
2
3
.toolbar {
EditButton()
}

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct ContentView: View {
private var oceans = [
Ocean(name: "Pacific"),
Ocean(name: "Atlantic"),
Ocean(name: "Indian"),
Ocean(name: "Southern"),
Ocean(name: "Arctic")
]
@State private var multiSelection = Set<String>()
var body: some View {
NavigationStack {
List(oceans, selection: $multiSelection) {
Text($0.name)
}
.navigationTitle("Oceans") // 导航栏的标题
.toolbar {
EditButton()
}
Text("当前选中:\(multiSelection.count)")
}
}
}

在上面的代码中,实现了一下几步:

  1. 通过NavigationStack 实现了导航栏;
  2. toolBar上添加了一个EditButton,当点击 EditButtonList 将进入可编辑模式
  3. 使用@State 定义了一个元素类型和Oceanid 类型(String)一致的动态元祖变量,然后将这个变量和List中的selection绑定,当 List 进入编辑模式之后我们就可以获取到被选中的List唯一ID

效果如下:

List 的下拉刷新加载

首先将数据源oceans 使用@State 声明为动态的响应式类型:

1
2
3
4
5
6
7
@State private var oceans = [
Ocean(name: "Pacific"),
Ocean(name: "Atlantic"),
Ocean(name: "Indian"),
Ocean(name: "Southern"),
Ocean(name: "Arctic")
]

然后给List添加一个refreshable 修饰器:

1
2
3
4
.refreshable {
// 每次刷新向 oceans 数组中添加一个新的元素
oceans.append(.init(name: "Other"))
}

此时,当程序运行后,每次下拉刷新List 中都将添加一个新的名为Other 的元素。