
Making Annotations in MapKit interactive with SwiftUI
Learn how to make interactive annotations on a Map view in SwiftUI.
When multiple annotations are being displayed on a map, it is important to add some interaction to the annotations themselves. This is most simple if the annotations are MKMapItem
objects, but if not, this can easily be achieved with tags.
To make it work you just need to provide a way for the Map view to know which of the annotations inside it is selected.
// Property to keep track of the selected annotation
@State var selectedTag: Int?
// Binding the property to the Map view
Map(selection: $selectedTag) {
Marker("Name", coordinate)
.tag(1)
}
The following view has a map with three markers on it:
import SwiftUI
import MapKit
struct ContentView: View {
private let mapMarkers: [(name: String, coordinate: CLLocationCoordinate2D)] = [
("Apple Developer Academy", CLLocationCoordinate2D(latitude: 40.836639, longitude: 14.306602)),
("Restaurant", CLLocationCoordinate2D(latitude: 40.834890, longitude: 14.304400)),
("Coffee Bar", CLLocationCoordinate2D(latitude: 40.836901, longitude: 14.302562))
]
var body: some View {
Map {
Marker(mapMarkers[0].name, coordinate: mapMarkers[0].coordinate)
Marker(mapMarkers[1].name, coordinate: mapMarkers[1].coordinate)
Marker(mapMarkers[2].name, coordinate: mapMarkers[2].coordinate)
}
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding()
}
}
Code for a Map View showing three annotations using SwiftUI
Create a property called selectedTag
that will be used to identify which annotation was selected by the user. Then let’s bind it to the Map
view through its selection
attribute.
Then make the annotations on the map identifiable with the .tag(:)
modifier.
struct ContentView: View {
@State var selectedTag: Int?
private let mapMarkers: [(name: String, coordinate: CLLocationCoordinate2D)] = [ ... ]
var body: some View {
Map(selection: $selectedTag) {
Marker(mapMarkers[0].name, coordinate: mapMarkers[0].coordinate)
.tag(1)
Marker(mapMarkers[1].name, coordinate: mapMarkers[1].coordinate)
.tag(2)
Marker(mapMarkers[2].name, coordinate: mapMarkers[2].coordinate)
.tag(3)
}
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding()
}
}
Enabling selection interaction for annotations in the map.
There is much more you can do with MapKit and SwiftUI. To see the latest updates on MapKit with SwiftUI check our article highlighting the updates made on WWDC in 2023.
