How to create SwiftUI Picker from Enum

⋅ 3 min read ⋅ SwiftUI Picker Enum

Table of Contents

Picker is a control for selecting an option from a set of mutually exclusive values.

That makes an Enum one of the data structures that best represent options for the Picker view.

In this article, we will learn what you need to do to use Enum to populate SwiftUI Picker.

How to create SwiftUI Picker from Enum

To create a SwiftUI picker with Enum, your enum should conform to three protocols.

  1. CaseIterable.
  2. Identifiable.
  3. CustomStringConvertible.

Let's say we want to allow users to set their preferences on "auto-join hotspot".

And we create an enum of available auto-join hotspot options.

enum AutoJoinHotspotOption {
case never
case askToJoin
case automatic
}

And we want to produce a picker from these enum cases.

Picker from an enum cases.
Picker from an enum cases.

The Final result

Let's start with the final result.

This is what our picker will look like.

struct ContentView: View {
@State private var selectedOption: AutoJoinHotspotOption = .never

var body: some View {
Picker("Auto-Join Hotspot", selection: $selectedOption) {
// 1
ForEach(AutoJoinHotspotOption.allCases) { option in
// 2
Text(String(describing: option))
}
}
.pickerStyle(.wheel)
}
}

Our enum needs to do two things.

  1. We need to be able to get all cases of the enum. This will use to populate Picker. That's why we need CaseIterable and Identifiable protocols.
  2. We need to represent an enum case as a text value. That's why we need the CustomStringConvertible protocol. This is not mandatory. It depends on your use case.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

CaseIterable

Since you want to populate your picker with an enum, you need a way to get all cases in a format that a picker understands.

And that is the CaseIterable job.

enum AutoJoinHotspotOption: CaseIterable {    
case never
case askToJoin
case automatic
}

By making an enum conform to CaseIterable, you got synthesized allCases property that returns all the cases in order of the declaration.

AutoJoinHotspotOption.allCases
// [.never, .askToJoin, .automatic]

Identifiable

With CaseIterable, we can turn enum cases into a format that ForEach understands.

But ForEach still has one more requirement for its data: all the members must be Identifiable.

Picker("Auto-Join Hotspot", selection: $selectedOption) {
ForEach(AutoJoinHotspotOption.allCases) { option in
// 'ForEach' requires that 'AutoJoinHotspotOption' conform to 'Identifiable'
}
}

We can make an enum conform to Identifiable by providing the id that uniquely identifies each enum case.

enum AutoJoinHotspotOption: CaseIterable, Identifiable {
case never
case askToJoin
case automatic
// 1
var id: Self { self }
}

1 Enum case without associated value conforms to Hashable[1] by default. We can use self as an id.

CustomStringConvertible

The last protocol is CustomStringConvertible. This is not a requirement, but I use it to make an enum representable in a string format.

I use this to convert each case into a human-readable format.

enum AutoJoinHotspotOption: CaseIterable, Identifiable, CustomStringConvertible {
case never
case askToJoin
case automatic

var id: Self { self }

var description: String {
switch self {
case .never:
return "Never"
case .askToJoin:
return "Ask to Join"
case .automatic:
return "Automatic"
}
}
}

After that, I can convert the enum case to a string with Text(String(describing: option)).

struct ContentView: View {
@State private var selectedOption: AutoJoinHotspotOption = .never

var body: some View {
Picker("Auto-Join Hotspot", selection: $selectedOption) {
ForEach(AutoJoinHotspotOption.allCases) { option in
Text(String(describing: option))
}
}
.pickerStyle(.wheel)
}
}

That's all steps you need to do to populate SwiftUI Picker with an enum.


  1. SE-0185 Synthesizing Equatable and Hashable conformance. ↩︎


Read more article about SwiftUI, Picker, Enum, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
AttributedString in iOS 15

Learn a new improvement struct of an NSAttributedString.

Next
How to pop View programmatically in SwiftUI

Learn how to pop a view from a navigation view in SwiftUI.

← Home