跳转至
Structure

Picker

A control that lets you select an item.

Declaration

struct Picker<Label, SelectionValue, Content> : View where Label : View, SelectionValue : Hashable, Content : View

Overview

You create a picker by providing 3 things:

  1. A selection binding
  2. A label
  3. Content for the picker to display.

Set the selection parameter to a "current selection" binding.

Set the label to a view that describes the purpose of selecting content in the picker.

The content is what the picker displays.

For example, consider the following enumeration of ice cream flavors:

enum Flavor: String, CaseIterable, Identifiable {
    case chocolate
    case vanilla
    case strawberry

    var id: String { self.rawValue }
}
You can create a picker to select among these values by providing Text views in the picker initializer's content:

struct IceCreamView: View {
    @State private var selectedFlavor = Flavor.chocolate

    var body: some View {
        Picker("Flavor", selection: $selectedFlavor) {
            Text("Chocolate 🍫")
                .tag(Flavor.chocolate)
            Text("Vanilla 🍦")
                .tag(Flavor.vanilla)
            Text("Strawberry 🍓")
                .tag(Flavor.strawberry)
        }
        Text("Selected flavor: \(selectedFlavor.rawValue)")
    }
}
A gif displaying a view containing a default wheel style picker with three options, "Chocolate 🍫", "Vanilla 🍦", and "Strawberry 🍓", and a textview that reads "Selected flavor: (selectedFlavor.rawValue)"; each picker option is tagged to the a Flavor enum within the state variable selectedFlavor, which is used to populate the textview with the chosen flavor.

You append a tag to each text view so that the type of each selection matches the type of the bound state variable.

Iterating Over a Picker’s Options

To provide selection values for the Picker without explicitly listing each option, you can create the picker with a ForEach construct, like this:

struct IceCreamView: View {
    @State private var selectedFlavor = Flavor.chocolate

    var body: some View {
        Picker("Flavor", selection: $selectedFlavor) {
            ForEach(Flavor.allCases) { flavor in
                Text(flavor.rawValue.capitalized)
            }
        }
    }
}
A gif displaying a view containing a default wheel style picker with three options, "Chocolate", "Vanilla", and "Strawberry"; the picker uses a ForEach construct to populate its options.

In this case, ForEach automatically assigns a tag to the selection views, using each option's id, which it can do because Flavor conforms to the Identifiable protocol.

However, if the selection type doesn't match the input to the ForEach, you need to provide an explicit tag. The following example shows a picker that has a binding to a Topping type, even though the options are all Flavor instances. Each option uses tag(_:) to associate a topping with the flavor it displays.

enum Flavor: String, CaseIterable, Identifiable {
    case chocolate
    case vanilla
    case strawberry

    var id: String { self.rawValue }
    var suggestedTopping: Topping {
        switch self {
        case .chocolate:
            return .nuts
        case .vanilla:
            return .cookies
        case .strawberry:
            return .blueberries
        }
    }
}
enum Topping: String, CaseIterable, Identifiable {
    case nuts
    case cookies
    case blueberries

    var id: String { self.rawValue }
}

struct ContentView: View {
    @State private var suggestedTopping: Topping = .cookies
    var body: some View {
        Picker("Suggest a topping for:", selection: $suggestedTopping) {
            ForEach(Flavor.allCases) { flavor in
                Text(flavor.rawValue.capitalized)
                    .tag(flavor.suggestedTopping)
            }
        }
        Text("suggestedTopping: \(suggestedTopping.rawValue)")
    }
}
A gif displaying a view containing a default wheel style picker with three options, "Chocolate", "Vanilla", and "Strawberry", and a textview that reads "suggestedTopping: (suggestedTopping.rawValue)"; a ForEach construct containing the  Flavor enum populates the options and returns a suggested topping for each, which is used to populate the textview.

Styling Pickers

You can customize the appearance and interaction of pickers by creating styles that conform to the PickerStyle protocol. You create your own style or use one of the styles provided by SwiftUI, like SegmentedPickerStyle or PopUpButtonPickerStyle.

To set a specific style for all picker instances within a view, use the pickerStyle(_:) modifier.

struct ContentView: View {
    @State private var selectedFlavor = Flavor.chocolate
    var body: some View {
        Picker("Flavor", selection: $selectedFlavor) {
            Text("chocolate")
                .tag(Flavor.chocolate)
            Text("vanilla")
                .tag(Flavor.vanilla)
        }
        .pickerStyle(SegmentedPickerStyle())
    }
}
A gif displaying a view containing a segmented style picker with two options, "chocolate" and "vanilla".

Availability

iOS 13.0+

macOS 10.15+

tvOS 13.0+

watchOS 6.0+

Topics


Instance Property

body The content and behavior of the view.


Initializer

init(_:selection:content:) Creates a picker with a localized string key label.

init(_:selection:content:) Creates a picker with a string label.

init(selection:label:content:) Creates a picker with a custom label.


Type Alias

Body The type of view representing the body of this view.