Create and Style Picker in SwiftUI Form
Jul 08, 2024If 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:
- Default Picker Style
- Inline Picker Style
- NavigationLink Picker Style
- Segmented Picker Style
- 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
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:
Where to go next?
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.