# Pickers in SwiftUI

Hi all, in today’s post, I’m going to demonstrate the `Picker` view in SwiftUI and the standard styles of this view.

The code in this post is available [here](https://github.com/xavier7t/iOSDevX/tree/main/iOSDevX/202303-Mar%202023/Pickers%20in%20SwiftUI).

# Picker View and its initializer

In iOS 13, SwiftUI introduced the `Picker` view, which is a public struct and it allows the user to select a value from a provided list of values so that the data or UI can be updated accordingly.

To create a picker view, we can use the following initializer:

```swift
init(_ titleKey: LocalizedStringKey, selection: Binding<SelectionValue>, @ViewBuilder content: () -> Content)
```

The parameters are explained below:

* titleKey: LocalizedStringKey. This is basically a string, however, the title won’t be displayed in all cases. (See later for more details.)
    
* selection: Binding&lt;SelectionValue&gt;. The selection parameter expects a binding value, which holds a default value or a value that users have picked.
    
* content - this is the view where users can pick a value. Often we can define a `ForEach` to hold the values from an array, or all cases of an enumeration.
    

Now, let’s build a navigation view with different types of styled picker views.

# Step 1 - Set up the Content View

The first step is to replace the default `VStack` in the Content View with a Navigation Stack or Navigation View that holds a List. Don’t add padding to the list or the formatting might be impacted.

```swift
struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                //...More code will go here later
            }
            .navigationTitle("SwiftUI Pickers")
        }
    }
}
```

# Step 2 - Add an Enum as the data source

Say we need a picker for users to select a direction to go forward, let’s create an enum of type String, with four cases - north, south, east and west. Since we’re going to use these cases in a `ForEach` for the picker, make sure the enum conforms to the protocol `CaseIterable`.

```swift
    enum Direction: String, CaseIterable {
        case north = "North"
        case south = "South"
        case east = "East"
        case west = "West"
    }
```

# Step 3 - Create a Default Picker

As discussed in the initializer section, we need to pass a binding variable to hold the picked value, so let’s define a state property of Direction inside the view struct, and name it as `pickedDirection`.

```swift
struct ContentView: View {
    @State private var pickedDirection: Direction = .north
    var body: some View {
        //...
    }
}
```

And then, inside the list, let’s create a picker with its initializer of `titleKey`, `selection` and `content`.

The title key will be "Select a direction", and pass the binding value of `pickedDirection` (ie. `$pickedDirection`). And the content will be a `ForEach`.

```swift
List {
    Picker("Select a direction", selection: $pickedDirection) {
        ForEach(Direction.allCases, id: \.self) { direction in
            Text(direction.rawValue)
        }
    }
}
```

Note 1: The data we passed to the `ForEach` is from the `Direction` enum, since we made the enum conform to `CaseIterable`, we can all the method `allCases` to get all cases of the enum and iterate over them. Since the enum has a type of String, we can use `direction.rawValue` to get its string value instead of using its case name.

Note 2: The content closure of `ForEach` can be shortened to `Text($0.rawValue)` where `$0` stands for the direction of each case. So you can use the code below if you prefer the shorthand syntax.

```swift
List {
    Picker("Select a direction", selection: $pickedDirection) {
        ForEach(Direction.allCases, id: \.self) {
            Text($0.rawValue)
        }
    }
}
```

Now you can see that the picker is working! When you pick a value from the menu list, the selected value in the list will get updated as well.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678760689251/7ddd4353-a70b-4323-8a67-d33635a4f270.png align="center")

# Step 4 - Make the Picker View Reuseable

Before we move on to figure out different types of picker view styles, let’s make the picker view a property in the content view, so that we don’t have to repeat the picker code.

To do this, create a new computed property of type `some View`, give it a name `picker`.

Cut the code of the picker from Step 3, and paste it inside the computed property. Now we can reuse it.

And put `picker` inside the list and bring it back to the content view.

```swift
var picker: some View {
    Picker("Select a direction", selection: $pickedDirection) {
        ForEach(Direction.allCases, id: \.self) { direction in
            Text(direction.rawValue)
        }
    }
}
var body: some View {
    NavigationStack {
        List {
            picker
        }
        .navigationTitle("SwiftUI Pickers")
    }
}
```

# Step 5 - Picker Styles

Now let’s take a look a different picker styles. For each picker style, you can add the `picker` property with the style view modifier inside the list, below the first picker.

## MenuPickerStyle

```swift
picker
    .pickerStyle(.menu)
```

This style looks almost the same as the default picker style. However, notice that the selected value will be shown in the system tint color if the picker style is set to `.menu`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678761734867/776342f8-cf60-432e-ae83-e893a13d46f5.png align="center")

## SegmentedPickerStyle

The segmented picker style will present a row with all the options. This might look cool, however, it is not a good choice for a long list of options, or the options have a long description.

```swift
picker
    .pickerStyle(.segmented)
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678761784094/79a44e67-942c-4ea9-996e-bbc2d5bb85ab.png align="center")

## WheelPickerStyle

This is a commonly used picker, especially for options that can be shown in a temporarily presented view, like a sheet. And the users can scroll up and down, the value shown when the wheel stops will be picked automatically.

```swift
picker
    .pickerStyle(.wheel)
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678762338434/167c4eb7-221c-4d45-953d-915718f67cdf.png align="center")

## InlinePickerStyle

This style will show all the options available directly in the view so that we users don’t need to tap a button or a menu to expand the list - they can simply scroll up and down and tap a value. The selected value will be marked with a tint-colored checkmark in the row.

```swift
picker
    .pickerStyle(.inline)
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678762493793/1c323ae5-486a-43b9-875f-a07aaf9ee8fe.png align="center")

And that’s all for today, I hope this post helped you understand how to create a picker view and the differences between the picker styles.

If you find it helpful, please hit the like button or subscribe to my newsletter. And I’ll see you all in the next post.
