Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select a Picker with MenuPickerStyle outside of the label text

Tags:

swift

swiftui

I have a simple menu picker that I have placed within a rounded rectangle border and chevron image. I'd like for users to be able to tap anywhere within this rectangle to activate the showing of the picker options but no matter what it only seems to be selectable within the actual text (see image with highlighted blue border). Is there any way to achieve this without scaling the text?

I've tried adding padding and scaling modifiers with no such luck.

var body: some View {
    ZStack {
        HStack {
            Rectangle()
                .foregroundColor(Color.black)
                .frame(height: 40)
            Image(uiImage: Icon.chevronDown.image())
                .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 8))
        }
        .overlay(
            RoundedRectangle(cornerRadius: 5)
                .stroke(Color.black, lineWidth: 1)
        )
        .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
        Picker(selectedOption, selection: $selectedOption) {
            ForEach(options, id: \.self) { option in
                Text(option)
            }
        }
        .pickerStyle(MenuPickerStyle())
    }
}

picker menu

How can I make the white area between the rounded black border and the blue text selectable to active the menu picker options the same way as tapping on the actual blue text?

like image 832
Aaron Avatar asked Oct 24 '25 04:10

Aaron


1 Answers

Use Picker(selection:label:content:), which takes a View as the label: argument. Put everything you want as the tappable view inside the label: argument, like so:

var body: some View {
        
    Picker(selection: $selectedOption, label:
            
            HStack {
                Rectangle()
                    .foregroundColor(Color(.systemBackground))
                    .frame(height: 40)
                Image(systemName: "chevron.down")
                    .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 8))
            }
            .overlay(
                RoundedRectangle(cornerRadius: 5)
                    .stroke(Color.black, lineWidth: 1)
            )
            .overlay(
                Text("Picker Option \(selectedOption)")
            )
            .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
    ) {
        ForEach(options, id: \.self) { option in
            Text("Picker Option \(option)")
        }
    }
    .pickerStyle(MenuPickerStyle())
}

Update: The above code doesn’t work in Xcode 13 beta 5. Hopefully it’s a bug, but if not, here is a workaround: put the Picker in a Menu!

var body: some View {
        
    Menu {
        Picker("picker", selection: $selectedOption) {
            ForEach(options, id: \.self) { option in
                Text("Picker Option \(option)")
            }
        }
        .labelsHidden()
        .pickerStyle(InlinePickerStyle())

    } label: {

        HStack {
            Rectangle()
                .foregroundColor(Color(.systemBackground))
                .frame(height: 40)
            Image(systemName: "chevron.down")
                .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 8))
        }
        .overlay(
            RoundedRectangle(cornerRadius: 5)
                .stroke(Color.black, lineWidth: 1)
        )
        .overlay(
            Text("Picker Option \(selectedOption)")
        )
        .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
    }
}
like image 128
Adam Avatar answered Oct 26 '25 20:10

Adam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!