Skip to main content

Fly-to camera animation

This example demonstrates "flying" the map to a different location with a controlled animation using the Mapbox Maps SDK for iOS.

The example initializes a MapView with the satellite streets style and configures the camera with specific options for starting and ending positions. It sets up an atmosphere, adds terrain data with a RasterDemSource, and configures terrain exaggeration. It also sets up a tap gesture that allows users to tap anywhere on the map to trigger an animated transition between the starting and end positions called by the camera fly method.

PLAYGROUND
Location Helper

To experiment with camera pitch, bearing, tilt, and zoom and get values to use in your code, try our Location Helper tool.

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.

GlobeFlyToExample.swift
import Foundation
import UIKit
import MapboxMaps
import CoreLocation

final class ViewController: UIViewController {
private var mapView: MapView!
private var isAtStart = true
private var instuctionLabel = UILabel(frame: CGRect.zero)
private var cancelables = Set<AnyCancelable>()

private var cameraStart = CameraOptions(
center: CLLocationCoordinate2D(latitude: 36, longitude: 80),
zoom: 1.0,
bearing: 0,
pitch: 0)

private var cameraEnd = CameraOptions(
center: CLLocationCoordinate2D(latitude: 46.58842, longitude: 8.11862),
zoom: 12.5,
bearing: 130.0,
pitch: 75.0)

override func viewDidLoad() {
super.viewDidLoad()

mapView = MapView(frame: view.bounds, mapInitOptions: .init(styleURI: .satelliteStreets))
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.mapboxMap.setCamera(to: .init(center: CLLocationCoordinate2D(latitude: 40, longitude: -78), zoom: 1.0))
try! self.mapView.mapboxMap.setProjection(StyleProjection(name: .globe))

mapView.mapboxMap.onStyleLoaded.observeNext { _ in
try! self.mapView.mapboxMap.setAtmosphere(Atmosphere())
self.addTerrain()

}.store(in: &cancelables)

mapView.gestures.onMapTap.observe { [weak self] _ in
self?.animateCameraOnClick()
}.store(in: &cancelables)

instuctionLabel.text = "Tap anywhere on the map"
instuctionLabel.textColor = UIColor.black
instuctionLabel.textAlignment = .center
instuctionLabel.layer.backgroundColor = UIColor.gray.cgColor
instuctionLabel.layer.cornerRadius = 20.0
instuctionLabel.translatesAutoresizingMaskIntoConstraints = false

view.addSubview(mapView)
view.addSubview(instuctionLabel)
installConstraints()
}

func installConstraints() {
let safeView = view.safeAreaLayoutGuide

NSLayoutConstraint.activate([
instuctionLabel.topAnchor.constraint(equalTo: safeView.bottomAnchor, constant: -70),
instuctionLabel.bottomAnchor.constraint(equalTo: safeView.bottomAnchor, constant: -30),
instuctionLabel.leadingAnchor.constraint(equalTo: safeView.leadingAnchor, constant: 70),
instuctionLabel.trailingAnchor.constraint(equalTo: safeView.trailingAnchor, constant: -70)
])

}

func addTerrain() {
var demSource = RasterDemSource(id: "mapbox-dem")
demSource.url = "mapbox://mapbox.mapbox-terrain-dem-v1"
// Setting the `tileSize` to 514 provides better performance and adds padding around the outside
// of the tiles.
demSource.tileSize = 514
demSource.maxzoom = 14.0
try! mapView.mapboxMap.addSource(demSource)

var terrain = Terrain(sourceId: "mapbox-dem")
terrain.exaggeration = .constant(1.5)

try! mapView.mapboxMap.setTerrain(terrain)
}

private func animateCameraOnClick() {
instuctionLabel.isHidden = true
var target = CameraOptions()
if isAtStart {
target = self.cameraEnd
} else {
target = self.cameraStart
}
isAtStart = !isAtStart
mapView.camera.fly(to: target, duration: 12)

}
}
Was this example helpful?