Updated for Xcode 14.2
SwiftUI’s Map
view allows us to show annotation views on top of the map, including default markers and pins, as well as completely custom views.
This takes three steps:
MKCoordinateRegion
to track the center and zoom level of the map.MapPin
and MapMarker
annotations you can show, or you can use your own views.Whatever array of locations you have, the types you’re using must conform to Identifiable
so SwiftUI understands how to identify each item uniquely. For example, you might use something like this:
struct Location: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
If all you have is CLLocationCoordinate2D
data, you can use them directly by adding an extension such as this one:
extension CLLocationCoordinate2D: Identifiable {
public var id: String {
"\(latitude)-\(longitude)"
}
}
Anyway, here’s an example that puts everything together so you can see map pins over various capital cities:
struct City: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
struct ContentView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10))
let annotations = [
City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275)),
City(name: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508)),
City(name: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5)),
City(name: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667))
]
var body: some View {
Map(coordinateRegion: $region, annotationItems: annotations) {
MapPin(coordinate: $0.coordinate)
}
.frame(width: 400, height: 300)
}
}
Download this as an Xcode project
That uses the traditional pin style that iOS has had for years, but if you want the larger pin style you can use MapMarker
instead, like this: MapMarker(coordinate: $0.coordinate)
And if you want complete control, you can also pass in completely custom views – some text, an image, a NavigationLink
, and so on.
For example, we could draw a 4-point stroked circle over our capital cities like this:
MapAnnotation(coordinate: $0.coordinate) {
Circle()
.strokeBorder(.red, lineWidth: 4)
.frame(width: 40, height: 40)
}
SPONSORED Thorough mobile testing hasn’t been efficient testing. With Waldo Sessions, it can be! Test early, test often, test directly in your browser and share the replay with your team.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.