mapbox / mapbox/mapbox-maps-ios

SwiftUI view annotations claim every touch in their frame, blocking map gestures and annotations beneath

Open
#2,433 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged feature :green_apple:
Dominant language
Swift
Stars
601
Forks
196
PR merge metrics
No merged PRs in 30d

Description

New Feature

MapViewAnnotation content is arbitrary SwiftUI, and it's common for the visible content not to fill the annotation's frame — a callout anchored above a marker, an L-shaped composition, or any layout that needs padding to position content relative to the anchor point. Today the entire frame behaves as opaque to touches:

  • A tap on a transparent part of the frame never reaches onMapTapGesture. SingleTapGestureHandler only accepts touches where touch.view === mapView (Sources/MapboxMaps/Gestures/GestureHandlers/SingleTapGestureHandler.swift), so once the touch lands on the annotation's hosting view, the map gesture is out.
  • Annotations underneath that transparent region become untappable too, since the topmost annotation view wins hit-testing inside ViewAnnotationsContainer.

allowHitTesting(false) is all-or-nothing, so it can't express "interactive where my content is, transparent everywhere else" — which is exactly what a non-rectangular annotation needs.

Request: let view annotation hit-testing follow the content's own hit-test shape, so the host view declines points the SwiftUI content doesn't claim and touches fall through to annotations below and to the map's own gestures. Opt-in would be fine:

MapViewAnnotation(coordinate: coordinate) { ... }
  .hitTestingMode(.contentShape)  // vs. today's .bounds behaviour

Observed with 11.26.0, SwiftUI Map + MapViewAnnotation.

Why

Any annotation that isn't a filled rectangle silently eats map taps and occludes its neighbours. The workaround is to split one logical piece of UI into several content-sized annotations positioned with variableAnchors offsets — a marker annotation plus a separate callout annotation anchored .bottomLeft to the same coordinate — which duplicates state and forces one expand/collapse animation to be coordinated across two SwiftUI views that can't share @State. PR #2276 requested a related escape hatch (an overridable hitTest on the container), so this doesn't appear to be an isolated need.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading MapViewAnnotation and the hit-testing path through ViewAnnotationsContainer, then inspect how SingleTapGestureHandler distinguishes map touches from annotation-hosting views. Implement the requested opt-in content-shaped behavior while preserving current bounds behavior, and verify that transparent points reach map gestures and annotations underneath.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
mobile
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.