Flavors of SwiftUI Picker on macOS

January 26th, 2022

⏱ Reading Time: 6 mins

Picker view is what we would be calling a multi-tool, or the Swiss knife of programming when creating user interfaces with SwiftUI. And that’s because the same view can get various appearances, depending on the style that we assign to it and how we want it to appear.

It’s important to know in advance that picker view is quite dependent on the target platform that is about to be rendered. There are different picker variations for iOS, macOS and watchOS systems. In this post I’m focusing on the picker view on macOS, where I’m gathering together in one place the various available styles currently exist.

Note: If you are interested in reading about the SwiftUI picker in iOS, then check out this post.

Initializing a picker

In the following snippet you can see the initialization of a picker view, without applying any style yet:

In this initializer, the first argument is a custom text that will be used by the picker as label. If it’s not desirable to have one, we can simply pass an empty string.

The important one, however, is the selection argument. It expects the binding value of a state property that indicates the selected item of the picker at any given moment. It has to be a binding value, because the picker updates it every time the user makes a different selection. In this case it’s the following:

The default selection refers to the first item in this sample collection:

Inside the initializer’s closure we add the content of the picker view, or in other words, all the possible values we want to make available and choose from. We can enumerate them one by one, usually by using Text views, or we can do so in a loop; that’s useful in case where picker values exist in a collection, just like it happens with the pickerValues array in this example. The iteration takes place in a ForEach loop, and you can see how it works in the following snippet; it’s the implementation of the pickerContent() method shown above:

The Default picker style

On macOS, and if we don’t specify a specific style, the picker by default is displayed as a popup menu that contains all available values, and showing the selected one:

Picker with default style which is the menu style on macOS.

We can achieve the exact same result if we specify the DefaultPickerStyle() style. As it happens with many SwiftUI views, there is a view modifier that allows us to set a style to the picker, called pickerStyle(_:):

Alternatively, we may provide the .automatic value as argument, which also assigns the default appearance to the picker for the given platform.

The Menu picker style

Even though the picker will show up as a popup menu on macOS, in a different platform it will have another appearance. For example, on iOS it’s going to be a wheel. This is what the default (or automatic) style does; it makes the picker adapt to the platform that the app is running on.

However, we can override that and have the picker always appear as a menu. All it takes is to set the respective style like so:

Instead of initializing a MenuPickerStyle() instance, we can also provide the .menu value and keep things simpler:

The Segmented picker style

A picker style that might be familiar from iOS is the segmented style. A picker that adopts this style presents available options as tabs, where only one is selected at any given time. It’s a nice style to resort to if there are three to five options that users should choose from.

To make the picker get the segmented appearance, just pass a SegmentedPickerStyle instance as argument to the pickerStyle(_:) view modifier:

We may provide the .segmented value as well in order to keep things simpler:

Picker with segmented style.

The Radio Group picker style

I personally find this style quite interesting, as it allows to create a picker that presents its options as a group of radio buttons with no effort at all. In contrast to AppKit where a radio button is a standalone control, here it’s just a picker with a specific style.

To create such a picker we have to set an instance of the RadioGroupPickerStyle as the argument of the pickerStyle(_:) modifier:

Alternatively, we can specify the .radioGroup value as the argument of the modifier:

Both of the above two result to a group of radio buttons displayed vertically one after the other:

Picker with radio group style in vertical layout.

Although vertical is the default display for the radio buttons, we can change that and display them horizontally. To achieve that, there is an additional view modifier to use, named horizontalRadioGroupLayout(). Note though that most probably we’ll need to explicitly set a width for the buttons; it seems that the default buttons’ width is too small and values are getting truncated.

Here’s all that in code:

Picker with radio group style in horizontal layout.

There is another style that’s similar to radio group, called inline. Similarly as above, it creates a group of radio buttons which we can also layout horizontally. According to the documentation, the inline picker style is suitable in order to use the picker inline along with other views in the same container. To apply that style, provide either an InlinePickerStyle or the .inline value to the pickerStyle(_:) modifier:

Putting everything together

The above are all the available picker styles for the SwiftUI Picker view on macOS at the time of writing this post. After having presented them one by one, let’s gather them all in one single code snippet:

Pickers with all styles.

Overview

Depending on where and how you want to place and use a Picker view, there is specific range of available styles to choose from. Unfortunately, there is still no way to define a custom picker style, as opposed to other views, such as buttons. In any case, make your decision appropriately having the user experience in mind, and following Apple’s rules of course. For example, if you have a large list of options to display to users, then don’t use the segmented or radio group styles. The menu style is the most suitable one. No matter what, working with the Picker in SwiftUI hides no difficulties, so all you have to do is just to get the hang of it.

Thank you for reading! ????

Stay Up To Date

Subscribe to my newsletter and get notifiied instantly when I post something new on SerialCoder.dev.

    We respect your privacy. Unsubscribe at any time.