[SwiftUI 知识碎片] Debris-5 利用循环创建视图

1,393 阅读2分钟
更多内容欢迎关注公众号: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 特别有用,它允许我们展示可供用户选择的各种选项。

为了演示这一点,我们来定义一个这样的视图:

  1. 有一个所有可能的学生名字的数组
  2. 有一个@State 属性,存储当前选中的学生名字
  3. 创建一个 Picker 视图,要求用户选择它们最喜欢的,用上双向绑定的 @State 属性
  4. 使用 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])")
        }
    }
}

有几点需要明确:

  1. students 数组不需要被标记 @State ,因为它是常量,不会改变。
  2. selectedStudent 属性从0开始,并且可以改变,因此用 @State 标记。
  3. Picker 有一个标签,“Select your student”, 它告诉用户自己的功能,同时也提供给屏幕辅助描述性的文字。
  4. Picker 有一个对 selectedStudent 的双向绑定,这意味着一开始选择第0个,但当用户移动选项时,这个属性也会更新。
  5. ForEach内部,我们从0开始计数,直到学生名字数组的长度(但不包括)
  6. 对于每个学生名字,我们都创建了一个文本视图,展示那个学生的名字。

之后我们还会探索 ForEach 的其他用法,不过这个项目中暂时到此为止。

这个是项目概览的最后一部分了,让我们开始真正的coding吧。


我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~