Map Annotation in SwiftUI

DevTechie Inc
Jun 24, 2022

Map view in SwiftUI allows us to add map annotation with a simple API. Map view takes annotations as an array and place them on to the map.

For this, we will need to create a data structure which we will supply to the annotation parameter.

Out struct will be called AnnotationItem. This struct will conform to identifiable protocol and will have name and coordinate properties as shown below:

struct AnnotationItem: Identifiable {
    let id = UUID()
    var name: String
    var coordinates: CLLocationCoordinate2D
}
We will some Points Of Interest(POIs) in an extension to the AnnotationItem as shown below:

extension AnnotationItem {
    static var POI: [AnnotationItem] {
        [
            AnnotationItem(name: "Golden Gate Bridge", coordinates: CLLocationCoordinate2D(latitude: 37.779339, longitude: -122.433609)),
            AnnotationItem(name: "San Diego Zoo", coordinates: CLLocationCoordinate2D(latitude: 33.095829, longitude: -117.008797)),
            AnnotationItem(name: "Statue Of Liberty", coordinates: CLLocationCoordinate2D(latitude: 40.689247, longitude: -74.044502)),
            AnnotationItem(name: "Empire State Building", coordinates: CLLocationCoordinate2D(latitude: 40.74853801503154, longitude: -73.98590043614894)),
        ]
    }
}
With this setup, we are ready to include annotations into the map:

struct MapAnnotationExample: View {
    
    @State private var region = MKCoordinateRegion(center: AnnotationItem.POI[0].coordinates, latitudinalMeters: 5000, longitudinalMeters: 5000)
    
    var body: some View {
        Map(coordinateRegion: $region, annotationItems: AnnotationItem.POI) { item in
            MapMarker(coordinate: item.coordinates, tint: .green)
        }
        .edgesIgnoringSafeArea(.all)
    }
}
We can change MapMarker to MapPin with a simple word change as shown below:

struct MapAnnotationExample: View {
    
    @State private var region = MKCoordinateRegion(center: AnnotationItem.POI[0].coordinates, latitudinalMeters: 5000, longitudinalMeters: 5000)
    
    var body: some View {
        Map(coordinateRegion: $region, annotationItems: AnnotationItem.POI) { item in
            MapPin(coordinate: item.coordinates, tint: .green)
        }
        .edgesIgnoringSafeArea(.all)
    }
}
We are not limited to MapMarker or MapPin. We can create our own UI for a annotation view.

For this, we will use MapAnnotation struct and for the content parameter, we will create a ZStack along with few Image views, as shown below:

struct MapAnnotationExample: View {
    
    @State private var region = MKCoordinateRegion(center: AnnotationItem.POI[0].coordinates, latitudinalMeters: 5000, longitudinalMeters: 5000)
    
    var body: some View {
        Map(coordinateRegion: $region, annotationItems: AnnotationItem.POI) { item in
            MapAnnotation(coordinate: item.coordinates) { 
                ZStack {
                    Image(systemName: "flag.circle.fill")
                        .font(.largeTitle)
                    Image(systemName: "arrow.down")
                        .offset(y: 20)
                }.foregroundStyle(LinearGradient(colors: [Color.green, Color.pink], startPoint: .top, endPoint: .bottom))
                    .background(Circle())
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}
With that we have reached the end of this article. Thank you once again for reading. Subscribe to our weekly newsletter at https://www.devtechie.com