MapKit in SwiftUI: Overlays
In addition to adding content with markers, MapKit provides the ability to add overlays to a map. These overlays include MapCircle
, MapPolygon
, and MapPolyline
, which you can use to highlight content on the map, such as area boundaries, transportation routes, or points of interest.
To demonstrate the capabilities of overlays, use the following variables indicating coordinates on a map:
let location1 = CLLocationCoordinate2D(latitude: 40.413652, longitude: -3.681793)
let location2 = CLLocationCoordinate2D(latitude: 40.414951, longitude: -3.681856)
let location3 = CLLocationCoordinate2D(latitude: 40.416257, longitude: -3.680661)
let location4 = [
CLLocationCoordinate2D(latitude: 40.418197, longitude: -3.685186),
CLLocationCoordinate2D(latitude: 40.418528, longitude: -3.683695),
CLLocationCoordinate2D(latitude: 40.416122, longitude: -3.682697),
CLLocationCoordinate2D(latitude: 40.415787, longitude: -3.684226),
]
MapCircle
Add a circle to the map at the specified coordinate and radius. Additionally, you can apply the following modifiers:
foregroundStyle
: Specifies the style to use for the circle's content.mapOverlayLevel
: Specifies the position of the circle relative to the map content. Accepted values areaboveRoads
to position above roads but below labels, andaboveLabels
to position above both roads and labels.
Example:
Map {
// 1
MapCircle(center: location1, radius: CLLocationDistance(50))
.foregroundStyle(.red.opacity(0.6))
.mapOverlayLevel(level: .aboveRoads)
// 2
MapCircle(center: location2, radius: CLLocationDistance(50))
.foregroundStyle(.mint.opacity(0.6))
.mapOverlayLevel(level: .aboveLabels)
}
- A circle with a radius of 50 in red overlaid on the map road but below the labels.
- A circle with a radius of 50 in mint overlaid on both the map road and labels.
MapPolygon
Create a polygon on the map at the specified coordinates. Like in MapCircle
, you can use the foregroundStyle
and mapOverlayLevel
modifiers to give your MapPolygon
a special touch.
Example:
Map {
// 1
MapPolygon(coordinates: location4)
.foregroundStyle(.purple.opacity(0.6))
.mapOverlayLevel(level: .aboveRoads)
}
- A purple polygon overlaid on the map road but below the labels.
MapPolyline
Create a sequence of connected lines.
Example:
Map {
// 1
MapPolyline(coordinates: [location1, location3])
.stroke(.brown, lineWidth: 5)
}
- Create a brown polyline with a width of 5 using the
stroke
modifier between the coordinateslocation1
andlocation3
.
Where MapPolyline
shines is when combined with MKDirections
to create routes from a starting point to a destination. MKDirections
allows you to obtain directions and estimated travel time between two locations through Apple's servers.
For example, in your SwiftUI view, add the following variable:
@State private var route: MKRoute?
route
will define the route from location1
to location3
.
Add the following function:
func calculateDirections() async {
// 1
let request = MKDirections.Request()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: location1))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: location3))
request.transportType = .walking
// 2
let response = try? await MKDirections(request: request).calculate()
route = response?.routes.first
}
- Create a
request
variable of typeMKDirections.Request
to request routes from the starting pointlocation1
to the destination pointlocation3
by walking as the mode of transportation. - Calculate possible route directions based on the specified request and assign the first route to the
route
variable.
Once all the above is done, in your SwiftUI view, add:
Map {
// 1
if let route {
// 2
MapPolyline(route)
.stroke(.brown, lineWidth: 5)
}
}
.task {
// 3
await calculateDirections()
}
- Validate that
route
is notnil
before creating theMapPolyline
. - Create a brown polyline with a width of 5 using the
stroke
modifier with the route contained inroute
. - Call the
calculateDirections()
function.
If you want to read the Spanish version of this article, you can find it here: https://asynclearn.com/blog/mapkit-overlays-swiftui/