SwiftUI Picker with option for no selection?

Is it possible to create a Picker that gives the user to not make a choice? Here is my existing code:
Code Block swift @FetchRequest(entity: ItemCategory.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \ItemCategory.name, ascending: true)])var categories: FetchedResults<ItemCategory>@State private var selectedCategoryIndex = 0/* omitted */Section(header: Text("Category")) {	Picker(selection: $selectedCategoryIndex, label: Text("Category")) {		ForEach(0 ..< categories.count) {			if (categories[$0].name != nil) {				Text(categories[$0].name!)			}		}	}}

This code allows the user to pick an option, but because I set the selection index to 0 it forces that choice without further interaction. When I use an optional for the index, it breaks selection completely. No item can be selected in that case.

Additionally, 'categories' is a FetchedResults collection.


  1. Make your State variable optional

Code Block @State private var selectedCategoryIndex = Int?


2. Provide an option for "No selection" and tag it with nil as an optional Int to match it. Place it before or after your ForEach
Code Block Text("Nothing").tag(nil as Int?)// ForEach here


3. Cast your actual values as Optionals the same way
Code Block // ForEach hereText(categories[$0].name!).tag($0 as Int?)

I'd also consider using the actual object array in your Picker rather than the indices.

I learned almost all I know about SwiftUI Bindings (with Core Data) by reading a blog by Jim Dovey on Core Data Bindings (do a Google search - its worth it). The remainder is a combination of some research and quite a few hours of making mistakes.

So when I use Jim's technique to create Extensions on SwiftUI Binding then we end up with something like this...

public extension Binding where Value: Equatable {
init(_ source: Binding<Value>, deselectTo value: Value) {
self.init(get: { source.wrappedValue },
set: { source.wrappedValue = $0 == source.wrappedValue ? value : $0 }
)
}
}

Which can then be used throughout your code like this...

Picker("country", selection: Binding($selection, deselectTo: nil)) { ... }

OR

Picker("country", selection: Binding($selection, deselectTo: someOtherValue)) { ... }

OR when using .pickerStyle(.segmented)

Picker("country", selection: Binding($selection, deselectTo: -1)) { ... }

which sets the index of the segmented style picker to -1 as per the documentation for UISegmentedControl and selectedSegmentIndex.

The default value is noSegment (no segment selected) until the user touches a segment. Set this property to -1 to turn off the current selection.

SwiftUI Picker with option for no selection?
 
 
Q