Issue
This Content is from Stack Overflow. Question asked by kostodian
I am using SwiftUI and UIViewRepresentable to display a map with different coloured MKPolygons as well as MKAnnotations.
While I can get the polygons to render correctly, I cannot get more than one annotation to load at a time. I think it has something to do with the way I am calculating the value of ‘landmarks’ as it’s only reading a single line of the data array, but having trouble figuring out another way to calculate this.
I intend to add more polygons and annotations so looking for a scaleable solution and hoping my current approach is somewhat in the right direction.
My code as follows: (I’m a beginner so apologies if the approach I’m taking is ugly!)
import SwiftUI
import MapKit
fileprivate class BlueSector: MKPolygon {
}
fileprivate class RedSector: MKPolygon {
}
fileprivate class MapPins: NSObject, MKAnnotation {
let title: String?
let subtitle: String?
let coordinate: CLLocationCoordinate2D
init(title: String?,
subtitle: String?,
coordinate: CLLocationCoordinate2D) {
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
}
}
struct MapView: UIViewRepresentable {
let region: MKCoordinateRegion
let todCoordinates: [CLLocationCoordinate2D]
let oplCoordinates: [CLLocationCoordinate2D]
let mapPoints: [(title: String, subtitle: String, coordinate: CLLocationCoordinate2D)]
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
mapView.region = region
let todpolygon = BlueSector(coordinates: todCoordinates, count: todCoordinates.count)
mapView.addOverlay(todpolygon)
let oplpolygon = RedSector(coordinates: oplCoordinates, count: oplCoordinates.count)
mapView.addOverlay(oplpolygon)
let landmarks = MapPins(title: mapPoints[0].0, subtitle: mapPoints[0].1, coordinate: mapPoints[0].2)
mapView.addAnnotation(landmarks)
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let routePolyline = overlay as? MKPolygon {
let renderer = MKPolygonRenderer(overlay: routePolyline)
if overlay is BlueSector {
renderer.strokeColor = UIColor.systemBlue
renderer.lineWidth = 2
renderer.fillColor = UIColor.systemCyan
renderer.alpha = 0.5
} else {
renderer.strokeColor = UIColor.systemRed
renderer.lineWidth = 2
renderer.fillColor = UIColor.systemPink
renderer.alpha = 0.5
}
return renderer
}
return MKOverlayRenderer()
}
func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "pinAnnotation"
var annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
}
annotationView?.annotation = annotation
return annotationView
}
}
struct ContentView: View {
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: -24.1500, longitude: 133.2500),
span: MKCoordinateSpan(latitudeDelta: 50, longitudeDelta: 50)
)
// BLUE POLYGON COORDINATES
@State private var todCoordinates = [
CLLocationCoordinate2D(latitude: -23.1902, longitude: 127.0806),
CLLocationCoordinate2D(latitude: -24.2905, longitude: 128.0645),
CLLocationCoordinate2D(latitude: -26.0708, longitude: 128.0648),
CLLocationCoordinate2D(latitude: -28.4816, longitude: 130.4419),
CLLocationCoordinate2D(latitude: -28.4826, longitude: 130.4852),
CLLocationCoordinate2D(latitude: -28.1001, longitude: 131.3645),
CLLocationCoordinate2D(latitude: -30.2052, longitude: 133.5951),
CLLocationCoordinate2D(latitude: -29.0006, longitude: 136.4946),
CLLocationCoordinate2D(latitude: -28.0017, longitude: 137.5943),
CLLocationCoordinate2D(latitude: -26.1314, longitude: 138.2312),
CLLocationCoordinate2D(latitude: -22.1747, longitude: 136.3819),
CLLocationCoordinate2D(latitude: -21.5143, longitude: 136.2242),
CLLocationCoordinate2D(latitude: -21.2947, longitude: 136.1949),
CLLocationCoordinate2D(latitude: -21.1201, longitude: 131.5020),
CLLocationCoordinate2D(latitude: -23.1304, longitude: 128.2753),
CLLocationCoordinate2D(latitude: -23.1902, longitude: 127.0806),
];
// RED POLYGON COORDINATES
@State private var oplCoordinates = [
CLLocationCoordinate2D(latitude: -30.2052, longitude: 133.5951),
CLLocationCoordinate2D(latitude: -29.0006, longitude: 136.4946),
CLLocationCoordinate2D(latitude: -28.0017, longitude: 137.5943),
CLLocationCoordinate2D(latitude: -26.1314, longitude: 138.2312),
CLLocationCoordinate2D(latitude: -28.5948, longitude: 143.3004),
CLLocationCoordinate2D(latitude: -29.5342, longitude: 142.4100),
CLLocationCoordinate2D(latitude: -31.0006, longitude: 142.4837),
CLLocationCoordinate2D(latitude: -31.4744, longitude: 143.3102),
CLLocationCoordinate2D(latitude: -33.0014, longitude: 143.3050),
CLLocationCoordinate2D(latitude: -33.2030, longitude: 140.3420),
CLLocationCoordinate2D(latitude: -33.0506, longitude: 140.1330),
CLLocationCoordinate2D(latitude: -32.5153, longitude: 139.4819),
CLLocationCoordinate2D(latitude: -31.3500, longitude: 138.5950),
CLLocationCoordinate2D(latitude: -31.3456, longitude: 135.2446),
CLLocationCoordinate2D(latitude: -30.2052, longitude: 133.5951),
];
// ANNOTATION DATA FOR BOTH POLYGONS
@State private var mapPoints = [
(title: "TOD",
subtitle: "Tod",
coordinate: CLLocationCoordinate2D(latitude: -23.6980, longitude: 133.8807)),
(title: "OPL",
subtitle: "Opal",
coordinate: CLLocationCoordinate2D(latitude: -30.5929, longitude: 138.4039)),
];
var body: some View {
MapView(
region: region,
todCoordinates: todCoordinates,
oplCoordinates: oplCoordinates,
mapPoints: mapPoints
)
.edgesIgnoringSafeArea(.top)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Solution
This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.
This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.