更多内容欢迎关注公众号:Swift花园
在 SwiftUI 中利用循环一次创建多个视图很常见。举个例子,我们可能需要遍历一个名字的数组,为每个名字创建一个文本视图,或者遍历一个菜单的数组,将每个菜单展示为一张图片。
为此,SwiftUI 也提供给我们一种专门的视图类型 —— ForEach。是的,你没看错,是 ForEach 视图类型。它会遍历数组和范围,尽可能地按需创建视图。不仅如此,ForEach 并不受最多10个子元素的限制。
ForEach 为每一个它遍历过的项目运行闭包,把当前项目传入闭包。举个例子,如果我们从0到99遍历,它将传入0,然后是1,然后是2,直到99。
举个例子,下面的代码会创建一个包含100个行的表单:
Form {
ForEach(0 ..< 100) { number in
Text("Row \(number)")
}
}因为 ForEach 传的是一个闭包,我们可以将参数名简写成这样:
Form {
ForEach(0 ..< 100) {
Text("Row \($0)")
}
}当我们和 SwiftUI 的 Picker 视图打交道时,ForEach 特别有用,它允许我们展示可供用户选择的各种选项。
为了演示这一点,我们来定义一个这样的视图:
- 有一个所有可能的学生名字的数组
- 有一个
@State属性,存储当前选中的学生名字 - 创建一个
Picker视图,要求用户选择它们最喜欢的,用上双向绑定的@State属性 - 使用
ForEach遍历所有可能的学生名字,将它们变成文本视图
代码如下:
struct ContentView: View {
let students = ["Harry", "Hermione", "Ron"]
@State private var selectedStudent = 0
var body: some View {
VStack {
Picker("Select your student", selection: $selectedStudent) {
ForEach(0 ..< students.count) {
Text(self.students[$0])
}
}
Text("You chose: Student # \(students[selectedStudent])")
}
}
}有几点需要明确:
students数组不需要被标记@State,因为它是常量,不会改变。selectedStudent属性从0开始,并且可以改变,因此用@State标记。Picker有一个标签,“Select your student”, 它告诉用户自己的功能,同时也提供给屏幕辅助描述性的文字。Picker有一个对selectedStudent的双向绑定,这意味着一开始选择第0个,但当用户移动选项时,这个属性也会更新。- 在
ForEach内部,我们从0开始计数,直到学生名字数组的长度(但不包括) - 对于每个学生名字,我们都创建了一个文本视图,展示那个学生的名字。
之后我们还会探索 ForEach 的其他用法,不过这个项目中暂时到此为止。
这个是项目概览的最后一部分了,让我们开始真正的coding吧。
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~
