Skip to content

MapKit Customizations (SwiftUI)

A SwiftUI guide for coding agents. Also covers mapstyle imagery hybrid standard, satellite map ios, map controls compass scale, mapscope namespace, points of interest filter, map traffic toggle.

The iOS 17 MapKit API customizes a Map through modifiers: mapStyle for the cartography, interactionModes for gestures, and mapControls or mapScope for the control views.

Map Styles

mapStyle picks between standard (the default), imagery (satellite), and hybrid (imagery plus roads and names). Each style configures elevation; standard and hybrid also filter points of interest and toggle traffic.

Map { /* content */ }
  .mapStyle(.imagery(elevation: .realistic))
.mapStyle(
  .standard(
    elevation: .flat,
    pointsOfInterest: .excluding([.store]),
    showsTraffic: false
  )
)
.mapStyle(
  .hybrid(
    elevation: .flat,
    pointsOfInterest: .including([.airport]),
    showsTraffic: true
  )
)

Limiting Gestures

All map gestures are on by default. Pass a set to interactionModes to allow only some of pan, pitch, rotate, and zoom.

Map(interactionModes: [.pan, .pitch]) { /* content */ }

Map Controls

Importing MapKit with SwiftUI brings control views: MapScaleView, MapCompass, MapPitchToggle, MapUserLocationButton, and MapZoomStepper. Inside mapControls, SwiftUI places them per platform.

Map { /* content */ }
  .mapControls {
    MapScaleView()
    MapCompass()
  }

Placing Controls Yourself

The controls are plain views, so they can live anywhere in the hierarchy. To bind one to a specific map, create an identifier with @Namespace, pass it as the map's scope, pass the same value to each control, and close the loop with mapScope.

struct MapScopeExample: View {
  @Namespace private var favoritesMap

  var body: some View {
    VStack {
      Map(scope: favoritesMap) { /* favorite pins */ }

      HStack {
        MapScaleView(scope: favoritesMap)
        MapCompass(scope: favoritesMap)
          .mapControlVisibility(.hidden)
      }
    }
    .mapScope(favoritesMap)
  }
}

mapControlVisibility overrides the automatic visibility with always visible or hidden.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-mastering-mapkit-customizations" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems