Create and Style Picker in SwiftUI Form

swiftui Jul 08, 2024
Picker in SwiftUI Form

If you're working with a Form in SwiftUI, there are high chances that you will be required to implement a Picker component within the Form.

Picker in Form is generally used in the cases when you want to give users the flexibility to choose a value based on their preference out of a list of mutually exclusive values. SwiftUI provides various styling options to Picker with the .pickerStyle modifier.

One key thing to note is, since Form provides platform specific styling to views contained inside it, a particular Picker style might look different across platforms.

In this article, you are going to learn how to implement a Picker in Form on iOS in five different styles:

  1. Default Picker Style
  2. Inline Picker Style
  3. NavigationLink Picker Style
  4. Segmented Picker Style
  5. Wheel Picker Style

How to add Picker to a Form

For using a Picker, you first have to create either an array or an enum to contain the list of options and a @State variable to hold the selected value. A Picker requires three parameters, 1. Label, describing the purpose of picker 2. Selection Value, which is a binding to the @State variable, and 3. Content to be displayed Then, the Picker component is wrapped inside a Form.

Form {
    Picker("Picker Label", selection: $selectedValue) {
        pickerContent()
    }
}

Note: For this tutorial, we'll be using an array to store the options as it is not possible to have a multi word enumeration case in swift.

Default Picker Style

If you don't specify a .pickerStyle modifier, the styling of the Picker is default in nature. The options appear as a context menu overlaying the layout, when the picker view is clicked. When the user is not interacting with the Picker, the selected option is displayed on the right.

struct PickerInForm: View {
    let airdropOptions = ["Receiving Off", "Contacts Only", "Everyone for 10 minutes"]
    @State private var selectedAirdropOption = "Receiving Off"
    
    var body: some View {
        NavigationStack {
            Form {
                Section("AirDrop") {
                    Picker("Airdrop Options", selection: $selectedAirdropOption) {
                        ForEach(airdropOptions, id: \.self){ option in
                            Text(option)
                        }
                    }
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Result:

The default picker style can be applied explicitly by passing a value of automatic to the .pickerStyle modifier. And, both produces the same results.

struct PickerInForm: View {
    let airdropOptions = ["Receiving Off", "Contacts Only", "Everyone for 10 minutes"]
    @State private var selectedAirdropOption = "Receiving Off"
    
    var body: some View {
        NavigationStack {
            Form {
                Section("AirDrop") {
                    Picker("Airdrop Options", selection: $selectedAirdropOption) {
                        ForEach(airdropOptions, id: \.self){ option in
                            Text(option)
                        }
                    }
                    .pickerStyle(.automatic)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Result:

Inline Picker Style

As the name suggests, in Inline Picker Style the options are displayed in line with other views in the container meaning the picker options are integrated smoothly with the rest of the views, making them appear as part of the overall content rather than as a separate dropdown or popup. The selected option have a tick mark to it's right.

It is generally used when there are less than five options to be displayed.

This style is applied by passing the inline style value in the pickerStyle modifier.

struct PickerInForm: View {
    let airdropOptions = ["Receiving Off", "Contacts Only", "Everyone for 10 minutes"]
    @State private var selectedAirdropOption = "Receiving Off"
    
    var body: some View {
        NavigationStack {
            Form {
                Picker("Airdrop Options", selection: $selectedAirdropOption) {
                    ForEach(airdropOptions, id: \.self){ option in
                        Text(option)
                    }
                }
                .pickerStyle(.inline) 
            }
            .navigationTitle("Settings")
        }
    }
}

Result:

Note: While using Inline Picker Style with Form ensure that you don't use a Section component to wrap the picker view. If you do so, you'll see that the string passed as label appear as one of the list items along with other picker options.

NavigationLink Picker Style makes the label of the picker act as a navigation link. The selected option is displayed on the right which when clicked takes the user to another view where the options are presented as a list. To apply this style, you'll have to pass in the style value as navigationLink in the pickerStyle modifier.

The navigation link style is typically used in the cases when there are large number of options.

Apple generally uses NavigationLink Picker Style in it's native apps. For example, if you go to the setting apps of your iPhone, the "Auto-Join Hotspot" Wi-Fi setting options are listed using a NavigationLink Picker Style.

struct PickerInForm: View {
    let airdropOptions = ["Receiving Off", "Contacts Only", "Everyone for 10 minutes"]
    @State private var selectedAirdropOption = "Receiving Off"
    
    var body: some View {
        NavigationStack {
            Form {
                Section("AirDrop") {
                    Picker("Airdrop Options", selection: $selectedAirdropOption) {
                        ForEach(airdropOptions, id: \.self){ option in
                            Text(option)
                        }
                    }
                    .pickerStyle(.navigationLink)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Result:

Segmented Picker Style

Segmented Picker Style presents the options as segments and the one which is highlighted represents the selected one. As this style pushes all the option segments into a single row, it is advisable to use this in the case when you have just two to five options. This ensures that the options are clearly visible.

Segmented Picker Style is applied by passing the segmented style value in the pickerStyle modifier.

struct PickerInForm: View {
    let airdropOptions = ["Receiving Off", "Contacts Only", "Everyone for 10 minutes"]
    @State private var selectedAirdropOption = "Receiving Off"
    
    var body: some View {
        NavigationStack {
            Form {
                Section("AirDrop") {
                    Picker("Airdrop Options", selection: $selectedAirdropOption) {
                        ForEach(airdropOptions, id: \.self){ option in
                            Text(option)
                        }
                    }
                    .pickerStyle(.segmented)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Result:

Wheel Picker Style

Wheel Picker Style presents the picker options in a scrollable view with the selected one highlighted. At once only the selected one as well as few of it's neighbouring options are shown with the overall component given a fixed height irrespective of number of options.

For implementing this style, the style value of wheel is used.

struct PickerInForm: View {
    let airdropOptions = ["Receiving Off", "Contacts Only", "Everyone for 10 minutes"]
    @State private var selectedAirdropOption = "Receiving Off"
    
    var body: some View {
        NavigationStack {
            Form {
                Section("AirDrop") {
                    Picker("Airdrop Options", selection: $selectedAirdropOption) {
                        ForEach(airdropOptions, id: \.self){ option in
                            Text(option)
                        }
                    }
                    .pickerStyle(.wheel)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Result:

Picker in Form is a powerful control view that can be customized with various styles. As per your app's specific requirements you can adjust the appearance and behavior of the Picker.

Congratulations! You deserve to celebrate this moment. Today you learned about Picker in Forms in SwiftUI and five different picker styles that SwiftUI provides. If you want to learn more about Forms and how to implement other controls within a Form, we highly recommend you to read the article Forms in SwiftUI and other related articles like NavigationStack in SwiftUI.


We at Swift Anytime have the mission to make learn iOS development the way everyone enjoys it. You can check out our articles on SwiftUISwiftiOS Interview Questions and get started with your iOS journey today.​​

Signup now to get notified about our
FREE iOS Workshops!