Swiftui как пользоваться MKOverlayRenderer? - PullRequest
1 голос
/ 08 июля 2019

Я хочу нарисовать маршрут на карте.

, но структурировать без использования делегата.

struct MapView : UIViewRepresentable {
}

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

как я могу это сделать?

1 Ответ

0 голосов
/ 09 июля 2019

Вам нужно указать делегата, если вы хотите, чтобы mapView(_:rendererFor:) вызывался:

struct MapView: UIViewRepresentable {
    @Binding var route: MKPolyline?
    let mapViewDelegate = MapViewDelegate()

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

    func updateUIView(_ view: MKMapView, context: Context) {
        view.delegate = mapViewDelegate                          // (1) This should be set in makeUIView, but it is getting reset to `nil`
        view.translatesAutoresizingMaskIntoConstraints = false   // (2) In the absence of this, we get constraints error on rotation; and again, it seems one should do this in makeUIView, but has to be here
        addRoute(to: view)
    }
}

private extension MapView {
    func addRoute(to view: MKMapView) {
        if !view.overlays.isEmpty {
            view.removeOverlays(view.overlays)
        }

        guard let route = route else { return }
        let mapRect = route.boundingMapRect
        view.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), animated: true)
        view.addOverlay(route)
    }
}

class MapViewDelegate: NSObject, MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let renderer = MKPolylineRenderer(overlay: overlay)
        renderer.fillColor = UIColor.red.withAlphaComponent(0.5)
        renderer.strokeColor = UIColor.red.withAlphaComponent(0.8)
        return renderer
    }
}

Используется примерно так:

struct ContentView : View {
    @State var route: MKPolyline?

    var body: some View {
        MapView(route: $route)
            .onAppear {
                self.findCoffee()
        }
    }
}

private extension ContentView {
    func findCoffee() {
        let start = CLLocationCoordinate2D(latitude: 37.332693, longitude: -122.03071)
        let region = MKCoordinateRegion(center: start, latitudinalMeters: 2000, longitudinalMeters: 2000)

        let request = MKLocalSearch.Request()
        request.naturalLanguageQuery = "coffee"
        request.region = region

        MKLocalSearch(request: request).start { response, error in
            guard let destination = response?.mapItems.first else { return }

            let request = MKDirections.Request()
            request.source = MKMapItem(placemark: MKPlacemark(coordinate: start))
            request.destination = destination
            MKDirections(request: request).calculate { directionsResponse, _ in
                self.route = directionsResponse?.routes.first?.polyline
            }
        }
    }
}

Выход:

Coffee

...