通常在一个循环中创建多个SwiftUI视图。例如,我们可能想要遍历一系列名称,并让每个名称成为文本视图,或者遍历一系列菜单项,并将每个名称显示为图像。
SwiftUI为此提供了一个专用的视图类型,称为ForEach
。这可以在数组和范围上循环,根据需要创建尽可能多的视图。更妙的是,ForEach
不会像我们手动输入视图一样被10个视图限制所影响。
ForEach
将为其循环的每个项运行一次闭包,并传入当前循环项。例如,如果我们从0循环到100,它将传入0、1、2,依此类推。
例如,这将创建一个包含100行的窗体:
代码语言:javascript复制Form {
ForEach(0 ..< 100) { number in
Text("Row (number)")
}
}
因为ForEach
传入闭包,所以我们可以对参数名使用速记语法,如下所示:
Form {
ForEach(0 ..< 100) {
Text("Row ($0)")
}
}
ForEach
在使用SwiftUI的Picker
视图时特别有用,它允许我们显示各种选项供用户选择。
为了证明这一点,我们将定义一个视图:
1、有一系列可能的学生名字。 2、具有一个
@State
属性存储当前选定学生。 3、创建一个Picker
视图,要求用户选择他们最喜欢的,并将选择的值和@State
属性双向绑定。 4、使用ForEach
循环遍历所有可能的学生姓名,将其转换为文本视图。
这是相应的代码:
代码语言:javascript复制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])")
}
}
}
虽然代码不多,但有几点值得说明:
1、
students
数组不需要用@State
标记,因为它是一个常量,不会改变。 2、selectedStudent
属性初始值为0,但可以更改,这就是为什么它标记为@State
的原因。 3、Picker
有一个标签,“Select your student”(选择你的学生),它告诉用户它做了什么,还提供了一些描述性的东西供屏幕阅读器朗读。 4、Picker
与selectedStudent
有双向绑定,这意味着它将开始显示0的选择,但是在用户滑动选择器时更新属性。 5、在ForEach
中,我们从0数到(但不包括)数组中的学生数。 6、我们为每个学生创建一个文本视图,显示该学生的姓名。
我们将在未来研究使用ForEach
的其他方法,但这对于这个项目来说已经足够了。
这是这个项目概述的最后一部分,所以几乎是时候开始真正的代码了。如果要保存已编程的示例,则应将项目目录复制到其他位置。
准备好后,将ContentView.swift
放回最初创建项目时的方式,这样我们就有了一个干净的工作基础:
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello World")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Creating views in a loop