Skip to main content

Create a draggable marker with point annotations.

This example demonstrates how to create a draggable map marker using the PointAnnotation structure from the Mapbox Maps SDK for iOS.

In the code below, the camera is centered over New York City and PointAnnotation is adjusted as follows:

  • Placed at the center of the MapView.
  • Assigned a custom image.
  • Receives functionality that allows the marker to be dragged.

To render the PointAnnotation on the MapView, the structure needs to be added to the PointAnnotationManager, and to make it interactable, isDraggable must be assigned the value true. Lastly, you can adjust the PointAnnotation as it's being dragged by adding functionality to the dragBeginHandler and dragEndHandler.

Image Dependencies

This example uses a custom image:

This image is located in the Examples repository in the assets folder.

iOS Examples App Available

This example code is part of the Maps SDK for iOS Examples App, a working iOS project available on Github. iOS developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.

See our Run the Maps SDK for iOS Examples App tutorial for step-by-step instructions.

CustomPointAnnotationExample.swift
import UIKit
import MapboxMaps

final class ViewController: UIViewController {
private var mapView: MapView!
private let customImage = UIImage(named: "dest-pin")!
private var cancelables = Set<AnyCancelable>()

override func viewDidLoad() {
super.viewDidLoad()

// Center the map camera over New York City
let centerCoordinate = CLLocationCoordinate2D(latitude: 40.7128, longitude: -74.0060)
let options = MapInitOptions(cameraOptions: CameraOptions(center: centerCoordinate,
zoom: 9.0))

mapView = MapView(frame: view.bounds, mapInitOptions: options)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)

// Allows the delegate to receive information about map events.
mapView.mapboxMap.onMapLoaded.observeNext { [weak self] _ in
guard let self = self else { return }
self.setupExample()



}.store(in: &cancelables)
}

private func setupExample() {

// We want to display the annotation at the center of the map's current viewport
let centerCoordinate = mapView.mapboxMap.cameraState.center

// Make a `PointAnnotationManager` which will be responsible for managing
// a collection of `PointAnnotion`s.
// Annotation managers are kept alive by `AnnotationOrchestrator`
// (`mapView.annotations`) until you explicitly destroy them
// by calling `mapView.annotations.removeAnnotationManager(withId:)`
let pointAnnotationManager = mapView.annotations.makePointAnnotationManager()

// Initialize a point annotation with a geometry ("coordinate" in this case)
// and configure it with a custom image (sourced from the asset catalogue)
var customPointAnnotation = PointAnnotation(coordinate: centerCoordinate)
customPointAnnotation.image = .init(image: customImage, name: "my-custom-image-name")
customPointAnnotation.isDraggable = true
customPointAnnotation.iconOffset = [0, 12]
customPointAnnotation.tapHandler = { [id = customPointAnnotation.id] _ in
print("tapped annotation: \(id)")
return true
}

customPointAnnotation.dragBeginHandler = { annotation, _ in
annotation.iconSize = 1.2
return true // allow drag gesture begin
}
customPointAnnotation.dragEndHandler = { annotation, _ in
annotation.iconSize = 1
}

// Add the annotation to the manager in order to render it on the map.
pointAnnotationManager.annotations = [customPointAnnotation]
}
}
Was this example helpful?