In theory SwiftUI should give the child’s view gesture higher priority compared to parent's view gesture. And it is really so for most situations. But I encountered some situations where child's gestures stop work as expected.
For example Picker
of .pickerStyle(.segmented)
or a Button
inside a Form
.
How can we make those elements handle taps again?
import SwiftUI
struct ContentView: View {
@State private var message = "Message"
@State private var kind = Kind.item
@State private var isToggleOn = false
let newGesture = TapGesture().onEnded {
print("Tap on VStack.")
}
var body: some View {
VStack(spacing:25) {
// Elements responding to tap
Image(systemName: "heart.fill")
.resizable()
.frame(width: 75, height: 75)
.padding()
.foregroundColor(.red)
.onTapGesture {
print("Tap on image.")
}
Rectangle()
.fill(Color.blue)
Button("Button 1") {
print("Button 1 tapped")
}
Toggle("Toggle", isOn: $isToggleOn)
Picker("Kind", selection: $kind) {
ForEach(Kind.allCases) { kind in
Text(kind.description).tag(kind)
}
}
// Elements below stops responding to tap
Picker("Kind", selection: $kind) {
ForEach(Kind.allCases) { kind in
Text(kind.description).tag(kind)
}
}
.pickerStyle(.segmented)
Form {
Section {
Button("Button 2") {
print("Button 2 tapped")
}
} header: {
Text("Header")
}
}
}
.simultaneousGesture(newGesture)
.border(Color.purple, width: 3)
}
}
enum Kind: String, CaseIterable, CustomStringConvertible, Codable, Identifiable {
case item, service
var description: String {
switch self {
case .item:
return NSLocalizedString("Item", comment: "Item Kind in ItemModel")
case .service:
return NSLocalizedString("Service", comment: "Item Kind in ItemModel")
}
}
var id: Self { self }
}