Skip to main content

Interact with map

Last updated: March 25, 2026 | 3 minutes read

Use MapViewControllerDelegate, cursor selection APIs, and map-view preferences to handle user interactions, gestures, selections, and map render updates.

Understand gesture and event handling

The map handles common gestures (tap, double-tap, pan, pinch, rotate, shove) natively. To react to user interaction, implement callbacks in MapViewControllerDelegate.

InteractionDelegate callback (MapViewControllerDelegate)
TapmapViewController:onTouchPoint:
Long pressmapViewController:onLongTouchPoint:
Double tapmapViewController:onDoubleTouch:
Two-finger tapmapViewController:onTwoTouches:
PanmapViewController:onMovePoint:toPoint:
PinchmapViewController:onPinch:startPoint2:toPoint1:toPoint2:center:
ShovemapViewController:onShove:initial:start:end:

Gesture behavior explained:

  • Tap: Tap the screen with one finger. This gesture does not have a predefined map action.
  • Long press: Press and hold one finger on the screen. This gesture does not have a predefined map action.
  • Double tap: Zoom the map in by a fixed amount by tapping twice with one finger.
  • 2 finger tap: Align the map to north by tapping the screen with two fingers.
  • Pan: Move the map by pressing and holding one finger, then dragging in any direction. The map continues with slight momentum after release.
  • Pinch: Zoom in or out continuously by changing the distance between two fingers. You can also rotate continuously by changing the angle between two fingers.
  • Shove: With two fingers on the map, move both fingers together in parallel (typically up or down) to change the camera tilt angle while keeping the map center stable.
info

Gesture enable/disable is controlled per map using MapViewPreferencesContext.

Enable and disable gestures

let preferences = mapViewController.getPreferences()

_ = preferences.enableTouchGesture(.onMove, enable: false)
_ = preferences.enableTouchGesture(.onPinch, enable: true)

let enabledGestures = MapViewTouchGestures.onRotate.rawValue | MapViewTouchGestures.onShove.rawValue
_ = preferences.enableTouchGestures(Int32(enabledGestures), enable: true)

let rotateEnabled = preferences.isTouchGestureEnabled(.onRotate)
print("Rotate gesture enabled: \(rotateEnabled)")

Select map elements

Use cursor-based selection when you already have a screen point (for example from your own gesture recognizer).

func selectElements(at point: CGPoint, mapViewController: MapViewController) {
mapViewController.setCursorPosition(point)

let landmarks = mapViewController.getCursorSelectionLandmarks()
let streets = mapViewController.getCursorSelectionStreets()
let overlays = mapViewController.getCursorSelectionOverlayItems()
let routes = mapViewController.getCursorSelectionRoutes()
let trafficEvents = mapViewController.getCursorSelectionTrafficEvents()

print("landmarks=\(landmarks.count) streets=\(streets.count) overlays=\(overlays.count)")
print("routes=\(routes.count) traffic=\(trafficEvents.count)")
}

You can also receive selection directly from delegate callbacks such as:

Selection typeDelegate callback (MapViewControllerDelegate)
LandmarksmapViewController:didSelectLandmarks:onTouchPoint: and mapViewController:didSelectLandmarks:onLongTouchPoint:
StreetsmapViewController:didSelectStreets:onTouchPoint: and mapViewController:didSelectStreets:onLongTouchPoint:
RoutesmapViewController:didSelectRoutes:onTouchPoint:
OverlaysmapViewController:didSelectOverlays:, mapViewController:didSelectOverlays:onTouchPoint:, and mapViewController:didSelectOverlays:onLongTouchPoint:
Traffic eventsmapViewController:didSelectTrafficEvents:, mapViewController:didSelectTrafficEvents:onTouchPoint:, and mapViewController:didSelectTrafficEvents:onLongTouchPoint:
danger

Avoid heavy work inside touch or render callbacks. Long-running operations can reduce map responsiveness.

Observe render and camera movement

Use render callbacks to react to loading completion or camera movement status.

mapViewController.setOnMapViewRendered { dataStatus, cameraStatus in
if dataStatus == .complete && cameraStatus == .stationary {
print("Map is fully rendered and camera is stationary")
}
}

You can also use delegate methods:

  • mapViewController:willRender:
  • mapViewController:didRender:cameraTransitionStatus:

Capture the map as an image

let targetSize = CGSize(width: 1080, height: 1920)

// Use CGRect.zero to capture the entire map view
let image = mapViewController.snapshotImage(withSize: targetSize, captureRect: .zero)

if image == nil {
print("Could not capture map image")
}
danger

Capturing the map view may not work correctly when map rendering is disabled.