> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/ios/ja/maps/llms.txt)

# Animate marker position

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/ios/ja/ios/ja/assets/medias/AnimateMarker-a39efda30bee55f5017c864f06ef83b9.mp4).

This example demonstrates how to create a moving marker on a Mapbox map in iOS. The map displays a marker that can be animated by tapping anywhere on the map. When a tap is detected, the marker smoothly animates from its current position to the tapped location. The example sets the animation duration to 2 seconds.

The example utilizes the **Mapbox Maps SDK for iOS**, where a [`MapView`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/map-view/) is initialized with a marker image. The marker's position is updated by interpolating between the origin and destination coordinates over time. As the marker moves, the GeoJSON source for the marker's position is updated with the new marker location using the [`updateGeoJSONSource`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/stylemanager/updategeojsonsource(withid:data:dataid:)/) API.

The code includes handling a display link for smooth animation transitions, tap gesture handling to trigger marker movement, and setup functions to configure the map with the necessary data sources and layers.

> **Note: iOS Examples App Available**
> 
> This example code is part of the **Maps SDK for iOS Examples App**, a working iOS project [available on Github](https://github.com/mapbox/mapbox-maps-ios/tree/11.31.0/Sources/Examples). 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](https://docs.mapbox.com/help/tutorials/maps-sdk-ios-examples-app/) tutorial for step-by-step instructions.

**Swift**

Title: `AnimatedMarkerExample.swift`

[View on GitHub](https://github.com/mapbox/mapbox-maps-ios/blob/main/Sources/Examples/All%20Examples/Annotations/AnimatedMarkerExample.swift)

```swift
import Foundation
import MapboxMaps
import UIKit

final class ViewController: UIViewController {
    private var mapView: MapView!
    private var currentPosition = CLLocationCoordinate2D(latitude: 64.900932, longitude: -18.167040)
    private var animationStartTimestamp: CFTimeInterval = 0
    private var origin: CLLocationCoordinate2D!
    private var destination: CLLocationCoordinate2D!
    private var displayLink: CADisplayLink? {
        didSet { oldValue?.invalidate() }
    }
    private var cancelables = Set<AnyCancelable>()

    deinit {
        displayLink?.invalidate()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let cameraOptions = CameraOptions(center: currentPosition, zoom: 5)
        let initOptions = MapInitOptions(cameraOptions: cameraOptions)
        mapView = MapView(frame: view.bounds, mapInitOptions: initOptions)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(mapView)

        // Allows the delegate to receive information about map events.
        mapView.mapboxMap.onMapLoaded.observeNext { [weak self] _ in

            // Set up the example
            self?.setupExample()

            
            
        }.store(in: &cancelables)

        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = .white
        label.text = "Tap anywhere on the map"

        mapView.addSubview(label)

        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 32),
            label.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        ])

        mapView.mapboxMap.mapStyle = .standardSatellite

        // add a tap gesture handler that will allow the marker to be animated
        mapView.mapboxMap.addInteraction(TapInteraction { [weak self] context in
            self?.updatePosition(newCoordinate: context.coordinate)
            return true
        })
    }

    private func setupExample() {
        try? mapView.mapboxMap.addImage(UIImage(named: "dest-pin")!, id: Constants.markerIconId)

        // Create a GeoJSON data source.
        var source = GeoJSONSource(id: Constants.sourceId)
        source.data = .feature(Feature(geometry: Point(currentPosition)))

        try? mapView.mapboxMap.addSource(source)

        // Create a symbol layer
        var symbolLayer = SymbolLayer(id: "layer-id", source: Constants.sourceId)
        symbolLayer.iconImage = .constant(.name(Constants.markerIconId))
        symbolLayer.iconIgnorePlacement = .constant(true)
        symbolLayer.iconAllowOverlap = .constant(true)
        symbolLayer.iconOffset = .constant([0, 12])

        try? mapView.mapboxMap.addLayer(symbolLayer)
    }

    override func didMove(toParent parent: UIViewController?) {
        super.didMove(toParent: parent)

        // break reference cycle when moving away from screen
        if parent == nil {
            displayLink = nil
        }
    }

    @objc private func updateFromDisplayLink(displayLink: CADisplayLink) {
        let animationProgress = (CACurrentMediaTime() - animationStartTimestamp) / Constants.animationDuration

        guard animationProgress <= 1 else {
            displayLink.invalidate()
            self.displayLink = nil
            return
        }

        // interpolate from origin to destination according to the animation progress
        let coordinate = CLLocationCoordinate2D(
            latitude: origin.latitude + animationProgress * (destination.latitude - origin.latitude),
            longitude: origin.longitude + animationProgress * (destination.longitude - origin.longitude)
        )

        // update current position
        self.currentPosition = coordinate

        // update source with the new marker location
        self.mapView.mapboxMap.updateGeoJSONSource(withId: Constants.sourceId,
                                                              geoJSON: .feature(Feature(geometry: Point(coordinate))))

    }

    private func updatePosition(newCoordinate: CLLocationCoordinate2D) {
        // save marker's origin and destination to interpolate between them during the animation
        destination = newCoordinate
        origin = currentPosition
        animationStartTimestamp = CACurrentMediaTime()

        // add display link
        displayLink = CADisplayLink(target: self, selector: #selector(updateFromDisplayLink(displayLink:)))
        displayLink?.add(to: .current, forMode: .common)
    }
}

extension ViewController {
    enum Constants {
        static let markerIconId = "marker_icon"
        static let sourceId = "source-id"
        static let animationDuration: CFTimeInterval = 2
    }
}
```