Making Annotations in MapKit interactive with SwiftUI

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.

Using expanded SwiftUI support for MapKit
Learn how to use SwiftUI to integrate Maps in your apps with extended MapKit features like annotations, overlays, camera controls, and more.