Jack Wells
Jack Wells

Reputation: 21

(SwiftUI) MKOverlays (parsed from GeoJSON) are added, but do not show on screen, am I missing something?

I am attempting to show a UIKit/MapKit view in SwiftUI, following code very similar to this project on Github but implementing the GeoJSON render/overlay code from the Apple Guide for Optimizing Map Views with Filtering and Camera Constraints.

I have an 'EventDataSource' class which (successfully) parses the GeoJSON objects from a local file, in a UIViewRepresentable class, I then load this data, and add the overlays in the updateUIView function.

Placing a breakpoint in the mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) function shows that each polygon has the correct value for _pointCount, and I have added a print() line for the coordinates, which successfully prints out the coordinates of all the objects whenever the view is loaded.

Xcode shows no errors and builds fine, when run, the MapKit view loads, yet no overlays appear on screen.

The exact same mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) function, used in a UIKit ViewController renders the objects perfectly. In SwiftUI, I get successful parsing, yet only an empty map. Is there something I am missing?

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    var dataSource: EventDataSource = EventDataSource()

    func makeUIView(context: Context) -> MKMapView {
        let map = MKMapView()
        map.delegate = context.coordinator
        return map
    }

    func updateUIView(_ mapView: MKMapView, context: Context) {
        mapView.region = .event

        mapView.addOverlays(dataSource.overlays)
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    final class Coordinator: NSObject, MKMapViewDelegate {
        var control: MapView

        init(_ control: MapView) {
            self.control = control
        }

        func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {

            if let polygon = overlay as? MKPolygon {
                let renderer = MKPolygonRenderer(polygon: polygon)
                renderer.fillColor = UIColor(named: "OverlayFill")
                renderer.strokeColor = UIColor(named: "OverlayStroke")
                renderer.lineWidth = 1.0
                print("\(polygon.coordinate.longitude), \(polygon.coordinate.latitude)") // succesfully prints the coordinate of each object
                return renderer
            }
            else if let multiPolygon = overlay as? MKMultiPolygon {
                let renderer = MKMultiPolygonRenderer(multiPolygon: multiPolygon)
                renderer.fillColor = UIColor(named: "OverlayFill")
                renderer.strokeColor = UIColor(named: "OverlayStroke")
                renderer.lineWidth = 1.0
                print("\(multiPolygon.coordinate.longitude), \(multiPolygon.coordinate.latitude)") // succesfully prints the coordinate of each object
                return renderer
            }
            return MKOverlayRenderer(overlay: overlay)
        }
}

}

I have tried commenting out the line

mapView.addOverlays(dataSource.overlays)

When this line is not there, the coordinates do not print to the console, so I am sure that the function is being called.

Any help will be greatly appreciated, thanks!

Upvotes: 1

Views: 1955

Answers (1)

Nigel Gee
Nigel Gee

Reputation: 123

if you try this

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    var coordinate: CLLocationCoordinate2D

    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }

    func updateUIView(_ view: MKMapView, context: Context) {

        let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        view.setRegion(region, animated: true)
    }
}

then in your view add

MapView(coordinate: "the coordinates")

check out the https://developer.apple.com/tutorials/swiftui/creating-and-combining-views

Upvotes: 2

Related Questions