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

# Animate a view annotation

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

This example demonstrates how to create an animated [`ViewAnnotation`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/viewannotation/) on a map created with the **Mapbox Maps SDK for iOS**. The example sets up a [`MapView`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/mapview/) with a predefined route line displayed and animates an annotation along this route.

The annotation animation is achieved by calculating the progress based on a specified duration and updating the annotation's coordinates. The code includes setup for the [`MapView`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/mapview/), loading a GeoJSON route from a [`GeoJSONSource`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/geojsonsource/), and defining annotation properties such as the annotation view and anchor points.

> **Note (warning): Add AnnotationView class to your project**
> 
> This example uses [`AnnotationView`](https://github.com/mapbox/mapbox-maps-ios/blob/main/Sources/Examples/All%20Examples/Annotations/AnnotationView.swift/). To use this code snippet, you must also add the [AnnotationView class](https://github.com/mapbox/mapbox-maps-ios/blob/main/Sources/Examples/All%20Examples/Annotations/AnnotationView.swift/), a custom class defined in the Maps SDK for the [iOS Examples App](https://github.com/mapbox/mapbox-maps-ios/tree/main/Sources/Examples/).

> **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.29.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: `ViewAnnotationAnimationExample.swift`

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

```swift
import UIKit
import MapboxMaps
import CoreLocation

final class ViewController: UIViewController {
    private var mapView: MapView!
    private var cancelables = Set<AnyCancelable>()

    private lazy var route: LineString = {
        let routeURL = Bundle.main.url(forResource: "sf_airport_route", withExtension: "geojson")!
        let routeData = try! Data(contentsOf: routeURL)

        return try! JSONDecoder().decode(LineString.self, from: routeData)
    }()
    private lazy var totalDistance: CLLocationDistance = route.distance() ?? 0
    private var annotation: ViewAnnotation?
    private var animationStartTime: TimeInterval = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // center camera around SF airport
        let centerCoordinate = CLLocationCoordinate2D(latitude: 37.7080221537549, longitude: -122.39470445734368)
        let options = MapInitOptions(cameraOptions: CameraOptions(center: centerCoordinate, zoom: 11))

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

        mapView.mapboxMap.onStyleLoaded.observeNext { [weak self] _ in
            guard let self = self else { return }

            self.setupExample()
        }.store(in: &cancelables)
    }

    private func setupExample() {
        var source = GeoJSONSource(id: "route-source")
        source.data = .geometry(route.geometry)

        try! mapView.mapboxMap.addSource(source)

        var layer = LineLayer(id: "route-layer", source: source.id)
        layer.lineColor = .constant(StyleColor(UIColor.systemPink))
        layer.lineWidth = .constant(4)

        try! mapView.mapboxMap.addLayer(layer)

        let view = UIImageView(image: UIImage(named: "intermediate-pin"))
        view.contentMode = .scaleAspectFit
        let annotation = ViewAnnotation(coordinate: route.coordinates.first!, view: view)
        annotation.variableAnchors = [.init(anchor: .bottom, offsetY: -12)]
        mapView.viewAnnotations.add(annotation)
        self.annotation = annotation
    }

     else {
            mapView.mapboxMap.onMapLoaded.observeNext { _ in
                self.startAnimation()
            }.store(in: &cancelables)
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        animationStartTime = 0 // stops the animation
    }

    private func startAnimation() {
        let link = CADisplayLink(target: self, selector: #selector(animateNextStep))
        link.add(to: .main, forMode: .default)

        animationStartTime = CACurrentMediaTime()
    }

    @objc private func animateNextStep(_ displayLink: CADisplayLink) {
        let animationDuration: TimeInterval = 30
        let progress = (CACurrentMediaTime() - animationStartTime) / animationDuration
        let currentDistanceOffset = totalDistance * min(progress, 1)

        defer {
            if progress >= 1 {
                displayLink.invalidate()

                
                
            }
        }
        let currentCoordinate = route.coordinateFromStart(distance: currentDistanceOffset)!

        // set new coordinate to the annotation
        annotation?.annotatedFeature = .geometry(Point(currentCoordinate))
    }
}
```