SwiftUI — Picker

SwiftUI 中,Picker 是一个强大且灵活的选择器组件,用于提供选项选择功能。Picker 可以和数据进行绑定,UI 会随着数据的变化动态更新。它通常用于单列选择器或分段控件。


基本使用方式 #

在最简单的场景中,Picker 需要一个标题(供屏幕阅读器使用),一个绑定值(表示用户选中的选项),以及选项列表(例如在 ForEach 中生成)。

基础示例代码 #

import SwiftUI

struct BasicPickerExample: View {
    @State private var selectedOption = 0 // 用于存储用户选择的值
    let options = ["Option 1", "Option 2", "Option 3", "Option 4"]

    var body: some View {
        VStack {
            // 创建 Picker
            Picker("Please select an option", selection: $selectedOption) {
                ForEach(0..<options.count, id: \.self) { index in
                    Text(options[index]) // 添加每一个选项
                        .tag(index)       // 设置选项的标签值
                }
            }
            .pickerStyle(WheelPickerStyle()) // 样式用途说明见后文

            // 显示选择的内容
            Text("You selected: \(options[selectedOption])")
                .padding()
        }
    }
}

关键参数详解 #

  1. Picker 的标题

    • 第一个参数 "Please select an option",是系统为辅助功能和无障碍环境提供的内容。一般不会在 UI 中显示。
    • 辅助功能如屏幕阅读器会朗读该文字。
  2. selection 参数

    • selection 是一个绑定属性(Binding),用于存储和更新选中的值。
    • 这里通过 @State 将选中的选项值存储在 selectedOption 中。
  3. ForEach 渲染选项

    • 使用 ForEach 渲染 Picker 的选项,并为每个选项指定唯一的 tag 值。
    • tag 的值必须与绑定的值类型匹配,例如这里是 Int 索引。
    • 如果选项是字符串,可以直接将字符串作为 tag,例如下面的动态绑定示例。

样式选择 #

Picker 支持多种样式,以下是常见的样式:

  1. WheelPickerStyle

    • 默认滚轮样式选择器,类似 iOS 中的时间选择器。

    示例代码:

    .pickerStyle(WheelPickerStyle())
    
  2. SegmentedPickerStyle

    • 分段控件,用户通过按钮点击切换选项。
    • 常见于选项明确的设置切换场景。

    示例代码:

    .pickerStyle(SegmentedPickerStyle())
    
  3. MenuPickerStyle

    • 下拉菜单样式,适用于空间有限的场景。
    • 点击后弹出选项菜单。

    示例代码:

    .pickerStyle(MenuPickerStyle())
    

进阶使用 #

动态数据(字符串绑定) #

如果数据是数组,而不是静态选项,可以直接使用字符串的绑定,而不是通过索引。

示例代码 #

import SwiftUI

struct DynamicPickerExample: View {
    @State private var selected = "Option 1"
    let options = ["Option 1", "Option 2", "Option 3"]

    var body: some View {
        Picker("Select an option", selection: $selected) {
            ForEach(options, id: \.self) { option in
                Text(option).tag(option) // 使用字符串作 tag 值
            }
        }
        .pickerStyle(WheelPickerStyle()) // 滑轮样式
        .padding()

        Text("Selected: \(selected)") // 显示用户选择
    }
}

在这种情况下,Picker 的绑定值直接是所选字符串而不是索引值。


分段控件:SegmentedPickerStyle #

当选项较少且适合水平展示时,可以使用 SegmentedPickerStyle。例如设置“男”或“女”的选项。

示例代码 #

import SwiftUI

struct SegmentedPickerExample: View {
    @State private var selected = "Male"
    let options = ["Male", "Female"]

    var body: some View {
        VStack {
            Picker("Gender", selection: $selected) {
                ForEach(options, id: \.self) { option in
                    Text(option).tag(option)
                }
            }
            .pickerStyle(SegmentedPickerStyle()) // 分段样式
            .padding()

            Text("You selected: \(selected)")
        }
    }
}

弹出菜单样式:MenuPickerStyle #

MenuPickerStyle 适用于空间较小,且选项较多、视图需要保持简洁的情况。

示例代码 #

import SwiftUI

struct MenuPickerExample: View {
    @State private var selected = "Option 1"
    let options = ["Option 1", "Option 2", "Option 3"]

    var body: some View {
        VStack {
            Text("Select an option:")
            Picker("Drop down menu", selection: $selected) {
                ForEach(options, id: \.self) { option in
                    Text(option).tag(option)
                }
            }
            .pickerStyle(MenuPickerStyle()) // 菜单样式

            Text("You selected: \(selected)")
        }
        .padding()
    }
}

输出效果:点击 Picker 后会弹出一个下拉菜单,供用户选中。


多列组件(一般不直接用 Picker) #

对于类似于日期、时间选择的场景,推荐使用 DatePicker 等专门的组件,而不是 Picker。如果需要自定义「多列选择」,可以使用 HStack 将多个 Picker 垂直排列。

示例代码 #

以下是一种手动实现日期选择的多列 Picker:

import SwiftUI

struct MultiPickerExample: View {
    @State private var selectedYear = 2023
    @State private var selectedMonth = 1
    @State private var selectedDay = 1

    var body: some View {
        HStack {
            Picker("Year", selection: $selectedYear) {
                ForEach(2020...2030, id: \.self) { year in
                    Text("\(year)").tag(year)
                }
            }
            .frame(width: 100)
            .clipped()

            Picker("Month", selection: $selectedMonth) {
                ForEach(1...12, id: \.self) { month in
                    Text("\(month)").tag(month)
                }
            }
            .frame(width: 80)
            .clipped()

            Picker("Day", selection: $selectedDay) {
                ForEach(1...31, id: \.self) { day in
                    Text("\(day)").tag(day)
                }
            }
            .frame(width: 80)
            .clipped()
        }
        .pickerStyle(WheelPickerStyle()) // 滑轮样式
    }
}

完整总结 #

  • Picker 的基本结构

    • Pickerselection 属性绑定到一个 @State 或 Binding 数据,表示用户选中的结果。
    • 使用 ForEach 创建选项列表,并为每个选项设置唯一的 tag 值。
  • 支持的样式

    • WheelPickerStyle:滚轮选择器,默认样式。
    • SegmentedPickerStyle:分段控件。
    • MenuPickerStyle:下拉菜单。
  • 应用场景

    • 动态数据:通过字符串直接绑定值。
    • UI 样式与交互的灵活切换,例如切换日历、性别选项等。

在现代 SwiftUI 开发中,Picker 是高度数据绑定且方便灵活的选择组件,可以满足大多数选择需求!

本文共 1476 字,上次修改于 Jan 19, 2025