Home > Software engineering >  SwiftUI: How to generate a Map Route with transparent background?
SwiftUI: How to generate a Map Route with transparent background?

Time:04-12

I'm trying to create a map that will show the route of a workout, but I can't find anywhere in MapKit documentation as to how to customize the background, i.e. here I want the map itself to be transparent so that only the route (annotations) are visible. How can I do this?

struct MapOverlay: View {
    
    @ObservedObject var workoutDetailViewModel: WorkoutDetailViewModel
    
    var body: some View {
        if let unwrappedWorkoutLocations = workoutDetailViewModel.fullyLoadedWorkout?.workoutLocations {
            Map(
                coordinateRegion: .constant(
                    MKCoordinateRegion(
                        center: unwrappedWorkoutLocations.map {$0.coordinate}.center(), // Use the midpoint of the workout as the centre of the map.
                        span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)
                    )
                ),
                annotationItems: unwrappedWorkoutLocations.map {$0.coordinate}
            ) { routeLocation in
                MapAnnotation(coordinate: routeLocation) {
                    Circle().fill(TrackerConstants.AppleFitnessOrange)
                }
            }
            .cornerRadius(10)
            
        }
    }
}

struct MapOverlay_Previews: PreviewProvider {
    static var previews: some View {
        MapOverlay(workoutDetailViewModel: WorkoutDetailViewModel())
    }
}

CodePudding user response:

Don't use MKMapView. You want to take the coordinates and make a UIBezierPath from them, and render that into your own view, or a UIImage. Something like this playground:

import CoreLocation
import MapKit

let myCoords: [CLLocationCoordinate2D] = [
    .init(latitude: 42.42, longitude: 42.42),
    .init(latitude: 42.43, longitude: 42.425),
    .init(latitude: 42.425, longitude: 42.427),
    .init(latitude: 42.422, longitude: 42.426),
]

let r = MKPolylineRenderer(polyline: .init(coordinates: myCoords, count: myCoords.count))
let path = r.path!

let bezier = UIBezierPath(cgPath: path)
bezier.apply(.init(scaleX: 0.05, y: 0.05))

let renderer = UIGraphicsImageRenderer(bounds: .init(x: 0, y: 0, width: 640, height: 480))
let image = renderer
    .image { context in
        let size = renderer.format.bounds.size

        UIColor.darkGray.setFill()
        context.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))

        UIColor.black.setStroke()
        bezier.lineWidth = 5
        bezier.stroke()
}
  • Related