相关文章:


Picker

选择器与文本字段一样,需要与属性进行双向绑定,以便它们可以跟踪其值。

Picker(selection: $favoriteState, label: Text("Your name")) {                
	Text("Paul").tag("Paul")                
	Text("Chris").tag("Chris")                
	Text("Mark").tag("Mark")                

参数:label

Picker 必须加到 Form 视图里,label 标签才会显示。另外即使标签文本不可见,它仍然很有用,因为 VoiceOver 在阅读屏幕时会使用它。

// 首先,选择器可以设置 label 文字
Picker(label: Text("喜欢的课程")){ ... }

参数:selection

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的值可以是整数,也可以是字符串、布尔值等;它要和前面绑定的状态属性的类型一致,这样才能映射。

tag 选项值的设定

要获取或设置选择器的值,需要将其绑定到变量。 然后将此变量传递到选择器的初始化器中。 然后,您需要做的就是更改此绑定变量的值,以选择您想要在选择器中显示的行。 或者读取绑定变量的值,以查看当前选择的行。

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)")
        }
}

tag 可以是数组

例如用于切换排序规则上,选了哪个选项,就更新一个数组类型的状态属性。

@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

在子视图代码里设置 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 带有许多替代样式,具体取决于您希望事物的行为方式。

菜单样式 Menu

菜单样式,是选择器的默认样式。其表现是直接在当前页面展开一个小浮层,显示所有选项。

Picker("Picker Name", selection: $selected) {       
		ForEach(selectionOptions, id: \\\\.self) {
				Text($0)
		}
}
.pickerStyle(.menu)

menu.webp

行内样式 Inline

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

.pickerStyle(.inline)

inline.webp

轮子样式 wheel

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

.pickerStyle(.wheel)

wheel.webp

颜色选择器 Color Picker