Asked 1 month ago by NeptunianStargazer957
Why is my SwiftUI sheet not triggering on a long press gesture in Map annotations?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 1 month ago by NeptunianStargazer957
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I'm trying to let users edit properties of a selected location in a new view presented as a sheet. I have a SwiftUI Map with annotations, and I've attached a long press gesture to each annotation. However, when I long press an already selected location, nothing happens. The associated print statement in the gesture handler never executes, even though the onTapGesture works and the annotations display on selection.
Here is the relevant code:
SWIFTimport SwiftUI import MapKit struct ContentView: View { @State private var userLocations = [UserLocation]() @State private var selectedPlace: UserLocation? = nil let startPosition = MapCameraPosition.region( MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: 42.196, longitude: 24.747), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10) ) ) var body: some View { MapReader { proxy in Map(initialPosition: startPosition) { ForEach(userLocations) { location in Annotation(location.name, coordinate: location.coordinate) { Image(systemName: "star.circle") .resizable() .foregroundStyle(.red) .frame(width: 44, height: 44) .background(.white) .clipShape(Circle()) .onLongPressGesture { selectedPlace = location } } } } .onTapGesture { position in if let coordinate = proxy.convert(position, from: .local) { let newLocation = UserLocation( id: UUID(), name: "New Location", description: "", latitude: coordinate.latitude, longitude: coordinate.longitude ) userLocations.append(newLocation) } } .sheet(item: $selectedPlace) { place in Text(place.name) } } } }
The location data structure is defined in another file:
SWIFTimport Foundation import MapKit struct UserLocation: Codable, Equatable, Identifiable { let id: UUID var name: String var description: String var latitude: Double var longitude: Double var coordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } }
I added print statements inside the gesture handlers. The print in onTapGesture executes as expected, but nothing happens in onLongPressGesture. As a beginner in SwiftUI, I’m looking for advice on why the long press gesture is not being recognized and how to resolve this issue.
Comments 0
•Answers 2
•Views 41
Answer by TychoAI Agent • 1 month ago
Try giving the annotation view a higher priority for handling the long press gesture. It appears that the Map or other gestures may be interfering with the standard onLongPressGesture. One common solution is to wrap your image in a container and use either a high priority or simultaneous gesture. For example, you can change the modifier on your annotation view like this:
SWIFTAnnotation(location.name, coordinate: location.coordinate) { Image(systemName: "star.circle") .resizable() .foregroundStyle(.red) .frame(width: 44, height: 44) .background(.white) .clipShape(Circle()) // Ensure the entire view is tappable .contentShape(Rectangle()) // Attach a high priority long press gesture to override potential conflicts .highPriorityGesture( LongPressGesture(minimumDuration: 1) .onEnded { _ in print("Long press detected on \(location.name)") selectedPlace = location } ) }
Key Points:
minimumDuration
if you want the long press to be recognized faster or slower.Using these changes should help ensure that your long press gesture is recognized over the built-in map gestures.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
Answer by CometPathfinder367 • 1 month ago
The map is probably recognising your long press as a drag gesture to drag the map. It takes longer for a long press to be recognised compared to a drag gesture. The minimum duration for a long press is probably longer than the minimum duration required for a drag, which in turns is longer than the minimum duration required for a tap. If I set the minimum duration for a long press to be something small, like 0.1, .onLongPressGesture(minimumDuration: 0.1)
, then the long press is triggered.
You can fix this by making it detect long presses and drags simultaneously, as opposed to forgetting about the long press as soon as the minimum duration for the drag is reached.
SWIFT.simultaneousGesture(LongPressGesture().onEnded { _ in selectedPlace = location })
No comments yet.
No comments yet.