メインコンテンツまでスキップ

Create a static map snapshot

This example demonstrates the usage of the Snapshotter class from the Mapbox Maps SDK for iOS. The SnapshotterExample class allows users to take a snapshot of a MapView and display it on an UIImageView. By initializing a Snapshotter object, setting its properties such as size, map style, and camera, users can capture the current state of the map view through the startSnapshot() method. Upon completion, the resulting image is displayed in the associated UIImageView.

The initializeSnapshotter(with size:) method configures the Snapshotter with necessary options while observing map interactions to make sure a smooth snapshot process. The stackView manages the layout of the map view and snapshot image within the example. Users can customize the map appearance through map styles and camera options, creating a dynamic snapshotting experience integrated with Mapbox Maps functionalities.

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.

SnapshotterExample.swift
import UIKit
import MapboxMaps

final class ViewController: UIViewController {
private var cancelables = Set<AnyCancelable>()
private var mapView: MapView!
private var snapshotter: Snapshotter!
private var snapshotView: UIImageView!
private var snapshotting = false
private lazy var stackView: UIStackView = {
let stackView = UIStackView(frame: view.safeAreaLayoutGuide.layoutFrame)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.alignment = .fill
stackView.spacing = 12.0
return stackView
}()
override public func viewDidLoad() {
super.viewDidLoad()

mapView = MapView(frame: view.bounds)
mapView.translatesAutoresizingMaskIntoConstraints = false
mapView.mapboxMap.mapStyle = .standard(lightPreset: .dawn, showRoadLabels: false)
// Add the `MapViewController`'s view to the stack view as a
// child view controller.
stackView.addArrangedSubview(mapView)

// Add the image view to the stack view, which will eventually contain the snapshot.
snapshotView = UIImageView()
snapshotView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(snapshotView)

// Add the stack view to the root view.
view.addSubview(stackView)

NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])

if #available(iOS 15.0, *) {
view.backgroundColor = .systemMint
} else {
view.backgroundColor = .systemGray
}
if #available(iOS 13.0, *) {
snapshotView.backgroundColor = .systemGray4
} else {
snapshotView.backgroundColor = .systemGray
}
}

public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

let size = CGSize(
width: view.safeAreaLayoutGuide.layoutFrame.width,
height: (view.safeAreaLayoutGuide.layoutFrame.height - stackView.spacing) / 2)

if let snapshotter {
snapshotter.snapshotSize = size
} else {
initializeSnapshotter(with: size)
}
}

private func initializeSnapshotter(with size: CGSize) {
// Configure the snapshotter object with its size, map style, and camera.
let options = MapSnapshotOptions(
size: size,
pixelRatio: UIScreen.main.scale)

snapshotter = Snapshotter(options: options)
snapshotter.load(mapStyle: .standard(lightPreset: .dusk))

// Set the camera of the snapshotter

mapView.mapboxMap.onMapIdle.observe { [weak self] _ in
// Allow the previous snapshot to complete before starting a new one.
guard let self = self, !self.snapshotting else {
return
}

let snapshotterCameraOptions = CameraOptions(cameraState: self.mapView.mapboxMap.cameraState)
self.snapshotter.setCamera(to: snapshotterCameraOptions)
self.startSnapshot()
}.store(in: &cancelables)
}

public func startSnapshot() {
snapshotting = true
snapshotter.start(overlayHandler: nil) { ( result ) in
switch result {
case .success(let image):
self.snapshotView.image = image
case .failure(let error):
print("Error generating snapshot: \(error)")
}
self.snapshotting = false


}
}
}
このexampleは役に立ちましたか?