MapKit is a strong framework that enables builders so as to add maps, annotations, and location-based options to their iOS functions. With SwiftUI, you’ll be able to simply combine MapKit into your app and create interactive and dynamic maps that provide an incredible person expertise. On this tutorial, we’ll discover how you can work with maps and annotations in SwiftUI, and how you can customise the map type and digital camera place.
The MapKit Fundamentals
Let’s begin with the fundamentals of MapKit. The MapKit framework features a Map
view that builders can use to embed a map in any SwiftUI venture. Right here is an instance:
import SwiftUI import MapKit
struct ContentView: View { var physique: some View { Map() } } |
Earlier than utilizing the Map
view, you must import the MapKit
framework. Then, to create a map, merely instantiate a Map
view. If you happen to’ve opened the Preview canvas in Xcode, it is best to see a full display screen map within the simulator.

Altering the Preliminary Place with Map Digital camera
As an alternative of displaying a default location, the Map
view has one other init
methodology so that you can change the preliminary place of the map:
init( initialPosition: MapCameraPosition, bounds: MapCameraBounds? = nil, interactionModes: MapInteractionModes = .all, scope: Namespace.ID? = nil ) the place Content material == MapContentView<By no means, EmptyMapContent> |
You may an occasion of MapCameraPosition
because the preliminary place of the map. MapCameraPosition
accommodates numerous properties that you should utilize to manage which place or area is displayed, together with:
automated
merchandise(MKMapItem)
– for displaying a particular map merchandise.area(MKCoordinateRegion)
– for displaying a particular area.rect(MKMapRect)
– for displaying particular map boundaries.digital camera(MapCamera)
– for displaying an current digital camera place.userLocation()
– for displaying the person’s location
As an illustration, you’ll be able to instruct the map to show a particular area by utilizing .area(MKCoordinateRegion)
:
Map(initialPosition: .area(MKCoordinateRegion(heart: CLLocationCoordinate2D(latitude: 40.75773, longitude: –73.985708), span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)))) |
The coordinates within the above pattern is the GPS coordinates of Instances Sq. in New York. The worth of span
is used to outline your required zoom stage of the map. The smaller the worth, the upper is the zoom stage.

You probably have a specific location for show, you’ll be able to go a map merchandise because the preliminary place. Here’s a pattern code snippet:
extension CLLocationCoordinate2D { static let bigBen = CLLocationCoordinate2D(latitude: 51.500685, longitude: –0.124570) }
struct ContentView: View {
var physique: some View { Map(initialPosition: .merchandise(MKMapItem(placemark: .init(coordinate: .bigBen)))) } } |
Animating the Change of Map Place
The Map
view additionally offers an extra init
methodology that accepts a binding to MapCameraPosition
. If you must change the place of the map, this init
methodology is extra acceptable:
@State personal var place: MapCameraPosition = .automated
Map(place: $place) { . . . } |
For instance, if you wish to add two buttons for customers to modify between two places, you’ll be able to write the code like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
extension CLLocationCoordinate2D { static let bigBen = CLLocationCoordinate2D(latitude: 51.500685, longitude: –0.124570) static let towerBridge = CLLocationCoordinate2D(latitude: 51.505507, longitude: –0.075402) }
struct ContentView: View {
@State personal var place: MapCameraPosition = .automated
var physique: some View { Map(place: $place) .onAppear { place = .merchandise(MKMapItem(placemark: .init(coordinate: .bigBen))) } .safeAreaInset(edge: .backside) { HStack { Button(motion: { withAnimation { place = .merchandise(MKMapItem(placemark: .init(coordinate: .bigBen))) } }) { Textual content(“Huge Ben”) } .tint(.black) .buttonStyle(.borderedProminent)
Button(motion: { withAnimation { place = .merchandise(MKMapItem(placemark: .init(coordinate: .towerBridge))) } }) { Textual content(“Tower Bridge”) } .tint(.black) .buttonStyle(.borderedProminent) } } } } |
By wrapping the place
variable with withAnimation
, the map view will robotically animate the place change.

This animation works even higher whenever you present a MapCamera
with a pitch angle to create a 3D perspective. To see what occurs, you’ll be able to strive altering the place of Huge Ben within the following line of code:
place = .digital camera(MapCamera( centerCoordinate: .bigBen, distance: 800, heading: 90, pitch: 50)) |
If you preview the map view, the digital camera angle adjusts to point out a 3D perspective of the area.

Including Markers and Annotations

Markers are a helpful function in MapKit that help you show content material at a particular coordinate on the map. It provides an additional layer of knowledge to your map, reminiscent of a retailer or a restaurant. Markers could be personalized with a system picture and tint coloration, making them visually distinct and straightforward to acknowledge. Whether or not you’re constructing a navigation app or a journey information, markers are a helpful instrument that may make it easier to create a greater person expertise.
So as to add a marker, you’ll be able to create the Marker
view within the map content material builder closure like this:
Map(place: $place) { Marker(“Pickup right here”, coordinate: .pickupLocation) } |
Optionally, you’ll be able to customise the Marker
object with a system picture. To vary the colour of the marker, use the tint
modifier:
Marker(“Pickup right here”, systemImage: “automobile.entrance.waves.up”, coordinate: .pickupLocation) .tint(.purple) |
Along with Marker
, SwiftUI now consists of an Annotation
view in iOS 17 for indicating a location on a map. It capabilities equally to Marker
, however presents larger flexibility for personalization.
So as to add an annotation, you create an Annotation
view within the map content material closure. Here’s a pattern code snippet for including a easy annotation:
Map(place: $place) { Annotation(“Decide up”, coordinate: .pickupLocation, anchor: .backside) { Picture(systemName: “automobile.entrance.waves.up”) } } |
You will have the pliability to customise the annotation in a wide range of methods. By attaching totally different modifiers to it, you’ll be able to change its look and conduct. Moreover, you should utilize stack views to rearrange the totally different elements of the annotation and create a structure that fits your wants. Right here is an instance:
Annotation(“Decide up”, coordinate: .pickupLocation, anchor: .backside) { ZStack { Circle() .foregroundStyle(.indigo.opacity(0.5)) .body(width: 80, peak: 80)
Picture(systemName: “automobile.entrance.waves.up”) .symbolEffect(.variableColor) .padding() .foregroundStyle(.white) .background(Shade.indigo) .clipShape(Circle()) } } |
This outcomes an animated annotation as proven within the under illustration.

Altering the Map Model
By default, the map view renders the map in a typical type. Nevertheless, you’ll be able to change the type by utilizing the mapStyle
modifier:
Map {
} .mapStyle(.imagery(elevation: .practical)) |
This creates a map type primarily based on satellite tv for pc imagery. By specifying a practical
elevation, the map view renders a 3D map with a sensible look.

Optionally, you may also change the map type to hybrid like this:
Abstract
This tutorial covers how you can work with maps and annotations in SwiftUI, utilizing the MapKit framework. The newest model of SwiftUI presents further APIs and views for builders to additional customise the map view. By now, it is best to know how you can embed a map in your app and add an annotation to spotlight a location on the map.
If you wish to study extra about SwiftUI, don’t overlook to take a look at our Mastering SwiftUI e-book.