SwiftUI形式—挑选器

275 阅读2分钟

TextFieldToggle 之后,另一个常见的表单控件是Picker 。它让我们在一系列可能的选项中选择一个选项。

我们需要做的第一件事是拥有一个包含选项列表的数组。

var cities = ["Rome", "Milan", "Venice", "Florence"]

然后我们需要一个属性来存储所选择的选项。我们用@State ,因为那是会根据用户的输入而改变的东西。

@State private var selected = "Rome"

最后,我们使用一个Picker 视图。我们传递2个参数。第一个是一个标签,第二个是用于所选项目的属性,在封闭中我们为每个不同的选项添加一个文本视图,使用ForEach 视图。

Picker("What's your favorite city?", selection: $selected) {
    ForEach(cities, id: \.self) {
        Text($0)
    }
}

下面是我们的完整代码ContentView

struct ContentView: View {
    var cities = ["Rome", "Milan", "Venice", "Florence"]

    @State private var selected = "Rome"
    
    var body: some View {
        Form {
            Picker("What's your favorite city?", selection: $selected) {
                ForEach(cities, id: \.self) {
                    Text($0)
                }
            }
        }
    }
}

你可以试着运行它,它显示正确,默认的选项是可视化的。

但即使在预览模式下,或在模拟器中,你也无法点击它。

为什么?

因为你需要把它全部包在一个NavigationView

struct ContentView: View {
    var cities = ["Rome", "Milan", "Venice", "Florence"]

    @State private var selected = "Rome"
    
    var body: some View {
        NavigationView{
            Form {
                Picker("What's your favorite city?", selection: $selected) {
                    ForEach(cities, id: \.self) {
                        Text($0)
                    }
                }
            }
        }
    }
}

我们将在另一篇文章中讨论NavigationView

现在再次运行它,你可以看到标签变成了黑色而不是灰色。

你可以点击它,你会看到选项列表,有一个导航链接可以返回。

点击一个,你会看到所选的选项被可视化,而不是默认的选项。

你也可以避免为选项使用数组,直接使用文本视图,但你需要在每个视图上使用tag() 修改器来识别每个选项。

struct ContentView: View {
    @State private var selected = "Rome"

    var body: some View {
        NavigationView {
            Form {
                Picker("What's your favorite city?", selection: $selected) {
                    Text("Rome")
                        .tag("Rome")
                    Text("Milan")
                        .tag("Milan")
                    Text("Venice")
                        .tag("Venice")
                    Text("Florence").tag("Florence")
                }
            }
        }
    }
}