相关文章:
选择器与文本字段一样,需要与属性进行双向绑定,以便它们可以跟踪其值。
Picker(selection: $favoriteState, label: Text("Your name")) {
Text("Paul").tag("Paul")
Text("Chris").tag("Chris")
Text("Mark").tag("Mark")
Picker 必须加到 Form 视图里,label 标签才会显示。另外即使标签文本不可见,它仍然很有用,因为 VoiceOver 在阅读屏幕时会使用它。
// 首先,选择器可以设置 label 文字
Picker(label: Text("喜欢的课程")){ ... }
selection 参数是需要和【状态参数】双向绑定的,以此决定选择器的值是什么
//先要定义状态参数
@State private var favoriteState = 1
//将 selection 参数,双向绑定到状态参数
Picker(selection: $favoriteState){ ... }
// 选择器后面大括号的闭包,主要是设置选择器的 UI ,视图是什么样的
Picker(selection: $favoriteState, label: Text("喜欢的课程")){
Text("SwiftUI")
Text("React")
Text("SwiftUI")
}
// 选项一般用循环“数组”生成
Picker("How pay?", selection: $paymentType) {
ForEach(paymentTypes, id: \\.self) {
Text($0)
}
}
// 然后需要给闭包的每一项,后面添加 tag 修饰符
Picker(selection: $favoriteState, label: Text("喜欢的课程")){
Text("SwiftUI").tag(0)
Text("React").tag(1)
Text("SwiftUI").tag(2)
}
// tag的值可以是整数,也可以是字符串、布尔值等;它要和前面绑定的状态属性的类型一致,这样才能映射。
要获取或设置选择器的值,需要将其绑定到变量。 然后将此变量传递到选择器的初始化器中。 然后,您需要做的就是更改此绑定变量的值,以选择您想要在选择器中显示的行。 或者读取绑定变量的值,以查看当前选择的行。
// 示例:Picker 使用 tag(字符串) 来标识每一项
@State private var selectedName = "Paul"
var body: some View {
VStack {
Picker("Your name", selection: $selectedName) {
Text("Paul").tag("Paul")
Text("John").tag("John")
Text("Sarah").tag("Sarah")
}
Text("Selected name: \\(selectedName)")
}
}
例如用于切换排序规则上,选了哪个选项,就更新一个数组类型的状态属性。
@State private var sortOrder = [
SortDescriptor(\\User.name),
SortDescriptor(\\User.joinDate),
]
// 用 tag 修饰符,包裹具体选项的值(可以是任何值)。该值与状态属性绑定
Picker("Sort", selection: $sortOrder) {
Text("Sort by Name")
.tag([
SortDescriptor(\\User.name),
SortDescriptor(\\User.joinDate),
])
Text("Sort by Join Date")
.tag([
SortDescriptor(\\User.joinDate),
SortDescriptor(\\User.name)
])
}
在子视图代码里设置 tag 值,在父视图中实例化,实例化时再给他赋值。
// 父视图:实例化子视图时传入 name 参数,作为 tag 的值
Picker(selection: $youTuberName, label: Text("")) {
// 这里不要打tag,因为在子视图里打了
Row(name: "Sean")
Row(name: "Chris")
Row(name: "Mark")
}
// 子视图:加了tag,但是tag的值是未明确的,等待实例化时才能获取填入
struct Row : View {
// 接受一个参数
var name: String
var body: some View {
return HStack {
Image(systemName: "person.fill")
.padding(.trailing)
.foregroundColor(Color.red)
Text(name)
}
// 在return后打tag
.tag(name)
}
}
// 以上例子也可以通过 ForEach 循环创建
// 例如,将选项存储到数组中
var youTubers = ["Sean", "Chris", "Mark", "Scott", "Paul"]
// 第1个参数双向绑定状态参数
Picker(selection: $youTuberName, label: Text("")) {
// 从数组里进行循环
ForEach(youTubers, id: \\.self) {
// 设了个参数是name
name in
Row(name: name)
}
// 还是在抽出的子视图里加
struct Row : View {
var name: String
var body: some View {
HStack {
Image(systemName: "person.fill")
Text(name)
}
.tag(name)
}
}
如果希望不设置默认选中项,可以让状态属性的初始值不等于任何一个tag:
// 例如:让初始值等于 0
@State private var selection = 0
Picker("", selection: $selection) {
Text("One").tag(1)
Text("Two").tag(2)
Text("Three").tag(3)
}
Picker 带有许多替代样式,具体取决于您希望事物的行为方式。
菜单样式,是选择器的默认样式。其表现是直接在当前页面展开一个小浮层,显示所有选项。
Picker("Picker Name", selection: $selected) {
ForEach(selectionOptions, id: \\\\.self) {
Text($0)
}
}
.pickerStyle(.menu)

Inline Picker 与刚才看到的 Menu Picker 非常相似。主要区别在于,菜单选择器在点击选中项时会显示一个折叠的选项列表,而内联选择器默认情况下会显示所有可用选项。
.pickerStyle(.inline)

Wheel Pickers 是经典的轮盘式选择器,需要旋转轮盘来选择特定选项。当选项列表很长时,轮盘选择器比 Inline Pickers 更加紧凑,而且在这种情况下,选择也显而易见。
.pickerStyle(.wheel)
