Добавление SwiftUI CalloutView в MapKit - PullRequest
0 голосов
/ 20 марта 2020

Как добавить пользовательский calloutView для MapKitAnnotations, написанных на SwiftUI?

В настоящее время у меня есть этот код:

import SwiftUI
import MapKit
import CoreLocation
import UIKit

struct MapView: UIViewRepresentable {
    @Binding var userTrackingMode: MKUserTrackingMode
    @Binding var centerCoordinate: CLLocationCoordinate2D
    @Binding var selectedPlace: MKPointAnnotation?
    @Binding var showingPlaceDetails: Bool
    var annotations: [MKPointAnnotation]

    var locationManager = CLLocationManager()

    func setupManager() {
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.requestAlwaysAuthorization()
    }

    //Static
    func makeUIView(context: Context) -> MKMapView {
        //setupManager()
        let mapView = MKMapView()
        mapView.delegate = context.coordinator

        mapView.showsUserLocation = true
        locationManager.requestWhenInUseAuthorization()
        if CLLocationManager.locationServicesEnabled() {
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }
        mapView.setUserTrackingMode(.follow, animated: true)
        mapView.showsCompass = false

        // add annotation for Technical University and Mensa
        let annotation = MKPointAnnotation()
        annotation.title = "London"
        annotation.subtitle = "Capital of England"
        annotation.coordinate = CLLocationCoordinate2D(latitude: 51.5, longitude: 0.13)
        mapView.addAnnotation(annotation)


        return mapView
    }

    //Dynamic
    func updateUIView(_ uiView: MKMapView, context: Context) {
        if uiView.userTrackingMode != userTrackingMode {
            uiView.setUserTrackingMode(userTrackingMode, animated: true)
        }

        if annotations.count != uiView.annotations.count {
            uiView.removeAnnotations(uiView.annotations)
            uiView.addAnnotations(annotations)
        }
        print("updating")
    }

    //Initialise UIKit Map Coordinator
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView

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

        func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
            parent.centerCoordinate = mapView.centerCoordinate
        }

        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
            guard !(annotation is MKUserLocation) else {
                return nil
            }

            let identifier = "Placemark"

            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
            if annotationView == nil {
                //CALL ANNOTATION VIEW

                annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                annotationView?.canShowCallout = true
//                annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
                annotationView?.rightCalloutAccessoryView = UIHostingController(rootView: PopupView()) // THIS LINE RIGHT HERE!

            } else {
                annotationView?.annotation = annotation
            }
            return annotationView
        }

        func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) {
            if mode != parent.userTrackingMode {
                DispatchQueue.main.async {
                    self.parent.userTrackingMode = mode
                }
            }
        }
        func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
            guard let placemark = view.annotation as? MKPointAnnotation else { return }
            parent.selectedPlace = placemark
            parent.showingPlaceDetails = true

        }
    }
}

extension MKUserTrackingMode {
    fileprivate var description: String {
        switch self {
        case .follow: return "follow"
        case .followWithHeading: return "followWithHeading"
        case .none: return "none"
        @unknown default: return "unknown"
        }
    }
}

Метод viewForAnnotation в Координаторе - это точка, где я думаю, что должен что-то добавить, но что? Я не работаю со Storyboard или чем-то еще, я просто хочу всплывающее окно в SwiftUI на карте. Я не очень разбираюсь в UIKit, поэтому, пожалуйста, объясните, насколько это возможно для начинающих. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...