swiftswiftui

Disable a Picker option in SwiftUI


I am trying to disable an option of Picker in swiftUI. According documentation below code is suppose to work:


struct ContentView: View {
    let options = ["All", "Men", "Women", ]
    @State private var selectedOption = "All"

    var body: some View {
        Picker("Options", selection: $selectedOption) {
            ForEach(options, id: \.self) { option in
                Text(option)
                    .disabled(option == "All")
            }
        }
    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Unfortunately, It's not working where I have went wrong. Can anyone help!?


Solution

  • You can't disable an option in SwiftUI Picker. The disabled modifier can be applied on the whole picker. So one way is, you can filter the options when adding to the picker.

    let options = ["All", "Men", "Women"]
        @State private var selectedOption = "Men"
    
        var body: some View {
            Picker("Options", selection: $selectedOption) {
                ForEach(options, id: \.self) { option in
                    if option != "All" {
                        Text(option)
    
                    }
                }
            }
        } 
    

    Another option is, you can use SwiftUI Menu to make a custom Picker and get your expected result. Here you can disable any option you want,

           let options = ["All", "Men", "Women"]
            @State private var selectedOption = "Men"
    
            var body: some View {
                Menu {
                    ForEach(options, id: \.self) { option in
                        if option == "All" {
                            Button(action: {}) {
                                Text(option)
                                    .foregroundColor(.gray)
                            }
                            .disabled(true)
                        } else {
                            Button(action: {
                                selectedOption = option
                            }) {
                                Text(option)
                            }
                        }
                    }
                } label: {
                    Text(selectedOption)
                        .foregroundColor(.primary)
                        .padding(.horizontal)
                }
                .padding(.horizontal)
            }