Map Dead End
Status: ready
Symptom
A map is the only way to choose a location: a store, a pickup point, a branch, a clinic.
Task: choose the nearest open pickup point
Only path: pan the map, tap pins, read callouts, compare from memory
Where it shows up
Delivery and pickup, ride sharing, bank branches, clinics, travel, real estate, events, parking.
Why it blocks the task
Exploring a map with VoiceOver means dragging a finger and hoping to hit a pin. Switch Control can't pan or pinch. Pins overlap, and distance and opening hours are only in callouts, so comparing three options means opening three callouts and remembering them. The user needs "the closest open point", not "a pin somewhere".
A map is one view of the data. It shouldn't be the only path through the task.
Root cause
The map was treated as the data source instead of one presentation of it.
- Pins have no names.
- Distance and hours are only in callouts.
- There's no list, or the list is read-only.
- Filters apply to the map but not to the list.
- The address is confirmed by dragging a pin.
Before
Map {
ForEach(points) { point in
Marker("", coordinate: point.coordinate)
}
}
Fix
Verdict: a list of the same points next to the map, with the information that matters for the choice, and a selection action in each row. Pins keep their names.
Why: a list can be scanned, compared and selected with any input method. The map stays for users who want it.
Picker("View", selection: $mode) {
Text("Map").tag(Mode.map)
Text("List").tag(Mode.list)
}
.pickerStyle(.segmented)
if mode == .list {
List(visiblePoints) { point in
VStack(alignment: .leading) {
Text(point.name).font(.headline)
Text("\(point.distanceText) · \(point.hoursText)")
Button("Pick up here") { select(point) }
.accessibilityLabel("Pick up at \(point.name)")
.accessibilityInputLabels(["Pick up here", "Pick up at \(point.name)"])
.accessibilityAddTraits(selected == point ? .isSelected : [])
}
}
} else {
Map {
ForEach(visiblePoints) { point in
Marker(point.name, coordinate: point.coordinate)
}
}
}

Map and list use the same visiblePoints, with the same filters and sorting. If the map shows 5 points and the list shows 3, the user stops trusting both.
The visible text "Pick up here" isn't part of the label "Pick up at 8 Garden Street". Without the accessibilityInputLabels line, "Tap Pick up here" wouldn't match. The demo has the line.
For an address, the path is search → choose a result from a list → optional map preview → a text field for entrance notes. Not "drag the pin to the entrance".
Check
Profile: VoiceOver
Task: choose the nearest open pickup point
Expected: done from the list, without touching the map
each row reads name, distance, hours
the selected point says "Selected"
Profile: Switch Control
Task: the same
Expected: rows and filters are scan targets, no pan or pinch needed
Profile: Voice Control
Task: "Tap Pick up at 8 Garden Street"
Expected: selects that point directly
WCAG mapping
1.3.1 Info and Relationships: spatial data has a structured equivalent.2.5.1 Pointer Gestures: pan and pinch have alternatives.2.1.1 Keyboard: the task can be done without pointer gestures.
App Store and product risk
A map-only pickup or branch choice blocks a core task. The user sees what the business offers and can't get to it.