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

# Add an inset map

![Add a smaller inset map that visualizes the viewport of the main map.](https://docs.mapbox.com/ios/assets/ideal-img/maps-examples-inset-map.6c3c7e0.480.png)

This example demonstrates how to add an inset map in an iOS application using the **Mapbox Maps SDK for iOS**. The inset map is an additional smaller [`MapView`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/map-view/) that visualizes the viewport of the main map.

The main map allows gestures and updates the center of the inset map when moved and displays a [bounding box](https://docs.mapbox.com/help/glossary/bounding-box/) representing the main map viewport in the inset map as a yellow polygon.

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

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

```swift
// Add a main map and a small inset map that does not respond to gestures
// the inset map updates its center when the main map is moved
// the inset map displays a polygon based on the current viewport of the main map
import UIKit
import MapboxMaps

@objc(ViewController)
final class ViewController: UIViewController {
    static let styleUri = StyleURI(rawValue: "mapbox://styles/mapbox/cj5l80zrp29942rmtg0zctjto")!

    // create MapViews for the main map and the inset map
    private var mapView: MapView!
    private var insetMapView: MapView!
    private var cancelables = Set<AnyCancelable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        // set up the main map
        let cameraCenter = CLLocationCoordinate2D(latitude: 39.13954, longitude: -77.25637)
        let initOptions = MapInitOptions(
            cameraOptions: CameraOptions(center: cameraCenter, zoom: 6.52),
            styleURI: Self.styleUri
        )
        mapView = MapView(frame: view.bounds, mapInitOptions: initOptions)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.gestures.options.rotateEnabled = false

        view.addSubview(mapView)

        mapView.mapboxMap.onCameraChanged.observe { [weak self] event in
            self?.updateInsetMap(center: event.cameraState.center)
        }.store(in: &cancelables)

        setupInsetMapView()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        applyDarkNavigationBarOniOS26AndAbove()
    }

    

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        resetDarkNavigationBarOniOS26AndAbove()
    }

    private func setupInsetMapView() {
        let myInsetMapInitOptions = MapInitOptions(cameraOptions: CameraOptions(zoom: 0), styleURI: Self.styleUri )

        // position the inset map in the bottom left corner
        insetMapView = MapView(
            frame: CGRect(x: 8, y: (view.frame.size.height - 250), width: 120, height: 120),
            mapInitOptions: myInsetMapInitOptions
        )

        // hide the scaleBar, logo, and attribution on the inset map
        insetMapView.ornaments.options.scaleBar.visibility = .hidden
        insetMapView.ornaments.logoView.isHidden = true
        insetMapView.ornaments.attributionButton.isHidden = true

        // disable panning and zooming on the inset map
        insetMapView.gestures.options.panEnabled = false
        insetMapView.gestures.options.doubleTapToZoomInEnabled = false
        insetMapView.gestures.options.doubleTouchToZoomOutEnabled = false

        // add a border, radius, and shadow around the inset map
        insetMapView.layer.borderWidth = 2
        insetMapView.layer.cornerRadius = 10
        insetMapView.layer.borderColor = UIColor.gray.cgColor
        insetMapView.layer.shadowColor = UIColor.black.cgColor
        insetMapView.layer.shadowOffset = CGSize(width: 3, height: 3)
        insetMapView.layer.shadowOpacity = 0.7
        insetMapView.layer.shadowRadius = 4.0
        insetMapView.layer.masksToBounds = true

        view.addSubview(insetMapView)

        // when the inset map loads, add a source and layer to show the bounds rectangle for the main map
        insetMapView.mapboxMap.onMapLoaded.observeNext { [weak self] _ in
            guard let self else { return }

            let geoJSONSource = GeoJSONSource(id: "bounds")

            // Create a line layer
            var lineBoundsLayer = LineLayer(id: "line-bounds", source: geoJSONSource.id)
            lineBoundsLayer.lineWidth = .constant(2.5)
            lineBoundsLayer.lineColor = .constant(StyleColor(#colorLiteral(red: 1, green: 0.99608, blue: 0.11373, alpha: 1)))

            // Add the source and layers to the map style
            try! self.insetMapView.mapboxMap.addSource(geoJSONSource)
            try! self.insetMapView.mapboxMap.addLayer(lineBoundsLayer)

            self.updateInsetMap(center: self.mapView.mapboxMap.cameraState.center)
        }.store(in: &cancelables)

    }

    private func updateInsetMap(center: CLLocationCoordinate2D) {
        // set the inset map's center to the main map's center
        insetMapView.mapboxMap.setCamera(to: CameraOptions(center: center))

        // get the main map's bounds
        let bounds = mapView.mapboxMap.coordinateBounds(for: mapView.bounds)

        // create a geojson polygon based on the main map's bounds
        // use it to update the "bounds" source in the inset map
        let polygon = Polygon(
            outerRing: Ring(
                coordinates: [
                    CLLocationCoordinate2D(latitude: bounds.south, longitude: bounds.west),
                    CLLocationCoordinate2D(latitude: bounds.north, longitude: bounds.west),
                    CLLocationCoordinate2D(latitude: bounds.north, longitude: bounds.east),
                    CLLocationCoordinate2D(latitude: bounds.south, longitude: bounds.east),
                    CLLocationCoordinate2D(latitude: bounds.south, longitude: bounds.west)
                ]
            )
        )

        insetMapView.mapboxMap.updateGeoJSONSource(withId: "bounds", geoJSON: polygon.geometry.geoJSONObject)
    }
}
```