Skip to content

Style Switching (iOS)

Switch between SmartMaps styles at runtime, for example to support dark mode.

MapSession required

Remember to integrate the MapSession in your app. The MapSession must be called periodically every 10 minutes while the map is active.

Automatic Dark Mode (UIKit)

import UIKit
import MapLibre

class StyleSwitchingViewController: UIViewController {
    private var mapView: MLNMapView!
    private let apiKey = "[INSERT API-KEY]"

    private func styleURL(for traitCollection: UITraitCollection) -> URL {
        let styleName: String = {
            switch traitCollection.userInterfaceStyle {
            case .dark: return "dark"
            default: return "light"
            }
        }()
        return URL(string:
            "https://tiles.smartmaps.cloud/styles/v1/smartmaps/\(styleName)/style.json?apiKey=\(apiKey)&channel=app"
        )!
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView = MLNMapView(
            frame: view.bounds,
            styleURL: styleURL(for: traitCollection)
        )
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.setCenter(
            CLLocationCoordinate2D(latitude: 49.0069, longitude: 8.4037),
            zoomLevel: 12,
            animated: false
        )
        view.addSubview(mapView)
    }

    // Automatically switch style when system appearance changes
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
            mapView.styleURL = styleURL(for: traitCollection)
        }
    }
}

Automatic Dark Mode (SwiftUI)

import SwiftUI
import MapLibre
import MapLibreSwiftUI

struct AdaptiveMapView: View {
    @Environment(\.colorScheme) var colorScheme
    let apiKey = "[INSERT API-KEY]"

    var styleURL: URL {
        let styleName = colorScheme == .dark ? "dark" : "light"
        return URL(string:
            "https://tiles.smartmaps.cloud/styles/v1/smartmaps/\(styleName)/style.json?apiKey=\(apiKey)&channel=app"
        )!
    }

    var body: some View {
        MapView(styleURL: styleURL)
            .initialViewport(
                .centerAndZoom(
                    center: CLLocationCoordinate2D(
                        latitude: 49.0069,
                        longitude: 8.4037
                    ),
                    zoom: 12
                )
            )
    }
}

Style Picker with Segmented Control

class StylePickerViewController: UIViewController {
    private var mapView: MLNMapView!
    private let apiKey = "[INSERT API-KEY]"
    private let styles = ["light", "dark", "grey", "essential", "accessible", "satellite"]

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView = MLNMapView(
            frame: view.bounds,
            styleURL: URL(string:
                "https://tiles.smartmaps.cloud/styles/v1/smartmaps/light/style.json?apiKey=\(apiKey)&channel=app"
            )
        )
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.setCenter(
            CLLocationCoordinate2D(latitude: 49.0069, longitude: 8.4037),
            zoomLevel: 12,
            animated: false
        )
        view.addSubview(mapView)

        // Add segmented control
        let segmentedControl = UISegmentedControl(items: styles.map { $0.capitalized })
        segmentedControl.selectedSegmentIndex = 0
        segmentedControl.addTarget(self, action: #selector(styleChanged), for: .valueChanged)
        segmentedControl.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(segmentedControl)

        NSLayoutConstraint.activate([
            segmentedControl.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16),
            segmentedControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            segmentedControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16)
        ])
    }

    @objc private func styleChanged(_ sender: UISegmentedControl) {
        let styleName = styles[sender.selectedSegmentIndex]
        mapView.styleURL = URL(string:
            "https://tiles.smartmaps.cloud/styles/v1/smartmaps/\(styleName)/style.json?apiKey=\(apiKey)&channel=app"
        )
    }
}