Reputation: 6714
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())
}
}
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?
Upvotes: 4
Views: 2262
Reputation: 5145
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))
}
}
Upvotes: 6