In my app, I need to use a Picker
in two different places. In one place, it's to set a property to one of three values: A, B, or C. But, in another place, I want to use the picker to filter a array of items to show either all items (no filter) or only the A, B, or C items.
So, my first attempt was to create an enum
like so:
enum Category {
case all
case A
case B
case C
}
Using this, I can filter my list successfully. But, when I try to create a new item in the array, I don't want all
to be an option. The user should only see a picker with A, B, and C.
I could try:
enum Category {
case A
case B
case C
}
but then how do I add the all
option for the filter picker?
A tournament can be a men's, women's, or mixed tournament. On the screen where I list the tournaments, I want to be able to show all tournaments or just the men's, just the women's or just the mixed tournaments. So, I have a picker that spans the width of the iPhone. Looks and works great.
Obviously, when adding a new item to the list, I have to specify its category, but not "all". Also a picker.
So, in one case, I need three values, in the other case, I need the same three values with "All" added at the beginning.
You should define your enum
without the all
case, because all
is not a valid Category
for an item. (This is a programming guideline known as “make illegal states unrepresentable”.)
enum Category: Hashable, CaseIterable {
case a
case b
case c
}
With that definition, the Picker
for setting an item's property can look like this:
Picker("Category", selection: $category) {
ForEach(Category.allCases, id: \.self) { category in
Text(verbatim: "\(category)")
.tag(category)
}
}
Then you should recognize that your filter is optional. You can filter by item category, or you can perform no filtering. So your filter property should be declared optional:
@Binding var categoryFilter: Category?
The Picker
for setting the filter then needs to be careful to use optional tags:
Picker("Category Filter", selection: $categoryFilter) {
Text("None")
.tag(Category?.none)
ForEach(Category.allCases, id: \.self) { category in
Text(verbatim: "\(category)")
.tag(Category?.some(category))
}
}