How to fix onTapGesture not working on SwiftUI picker

Picker is a very useful feature in SwiftUI. It supports several picker styles (for reference, check this post). However, it doesn’t work well with onTapGesture. As of Xcode 12, when we try to add an onTapGesture to picker, the picker stops responding. For example, the following code which shows a SegmentedPicker won’t work well:

struct MyView: View {
    var body: some View {
        @State private var selection = 0
        private let categories = ["Category 1", "Category 2"]
       
        //...
        Picker(selection: $selection, label: Text("Category")) {
           ForEach(0..<categories.count) {                            
              Text(categories[$0])
           } 
        }.pickerStyle(SegmentedPickerStyle())
        .onTapGesture {
           print(selection)
        }
}

The picker should look like this:

However if we click on Category 2 or Category 3, the picker is not responsive. This is because our own onTapGesture will interfere with picker’s implementation. In order to solve this problem, we can create a binding, and use the setter to handle the content of onTapGesture.

struct MyView: View {
    var body: some View {
        @State private var selection = 0
        private let categories = ["Category 1", "Category 2"]

    let tapOption = Binding<Int>(
        get: {
           selection
        },
        set: {
           selection = $0

           //Add the onTapGesture contents here
           print(selection)
                        
        }
    )
       
        //...
        Picker(selection: tapOption, label: Text("Category")) {
           ForEach(0..<categories.count) {                            
              Text(categories[$0])
           } 
        }.pickerStyle(SegmentedPickerStyle())
}

Leave a ReplyCancel reply