I want to add a button to swiftui picker's label.
But the button is not clickable.
When I click on the button the picker is clicked.
How Do I make the picker take clicks only in the area of the selected value?
and the buttons take his clicks?
import SwiftUI
enum Animal: String, CaseIterable, Identifiable {
case dog
case cat
case bird
var id: String { self.rawValue }
}
struct ContentView: View {
@State private var selectedAnimal = Animal.dog
var body: some View {
Form {
Group {
Section(header: Text("Animales")) {
VStack{
Picker(
selection: $selectedAnimal,
content: {
ForEach(Animal.allCases, id:\.self) {
Text($0.rawValue)
}},
label: {
HStack {
Text ("Chose Animale")
Spacer ()
Button (
action: {
print ("clicked")
},
label: {
Image(systemName: "arrow.clockwise")
})
Spacer ()
}
}
)
}
}
}
}
}
}
To solve this issue we need to separate picker and button and block Form tracking click inside row (which is by default track entire row).
For first move button out of picker and place everything in HStack
, for second we need couple of tricks like tapGesture on label and non-default button style for button (for simplicity I used primitive button style, but it's better to create custom with appropriate highlight, etc.)
Here is a simplified updated and tested your code (Xcode 13 / iOS 15):
var body: some View {
Form {
Group {
Section(header: Text("Animales")) {
HStack{
HStack {
Text ("Chose Animale")
Spacer ()
}
.contentShape(Rectangle())
.onTapGesture {
// just blocker for label click
}
.overlay(
Button (
action: {
print ("clicked")
},
label: {
Image(systemName: "arrow.clockwise").foregroundColor(.blue)
})
.buttonStyle(PlainButtonStyle()) // << needed custom !!
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.layoutPriority(1) // << to cover much area
//.border(Color.red) // << for testing area
Picker("",
selection: $selectedAnimal,
content: {
ForEach(Animal.allCases, id:\.self) {
Text($0.rawValue)
}}
)
.labelsHidden() // << hide own label
.fixedSize() // << limit size !!
}
.listRowInsets(EdgeInsets()) // << consume row space !!
}
}
}
}