Swift Map和MapKit-添加叠加层并居中

问题描述

我正在学习如何使用SwiftUI和MapKit, 我尝试绘制一个MKCircle,但我无法在当前地图中心使圆心居中

如何使用MapView.centerCoordinate设置中心?

        //HERE 
        let center: CLLocationCoordinate2D! = CLLocationCoordinate2D() 
        // How to set center with the map center (MapView.centerCoordinate) ?

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    @Binding var circle: MKCircle?
    
    var locationManager = CLLocationManager()
    let mapViewDelegate = MapViewDelegate()
    var centerCoordinate: CLLocationCoordinate2D?

    func setupManager() {
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.requestAlwaysAuthorization()
    }
    
    func makeUIView(context: Context) -> MKMapView {
        
        setupManager()
        let mapView = MKMapView(frame: UIScreen.main.bounds)
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow
        
        return mapView
    }

    func updateUIView(_ view: MKMapView,context: Context) {
        
        view.delegate = mapViewDelegate                                              
        view.translatesAutoresizingMaskIntoConstraints = false   
        addCircle(to: view)
    }
}

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

        guard let circle = circle else { return }

        
        //HERE 
        let center: CLLocationCoordinate2D! = CLLocationCoordinate2D() 
        // How to set center with the map center (MapView.centerCoordinate) ?
        
        
        let circle = MKCircle(center: center,radius: CLLocationdistance(1000))
        
        let mapRect = circle.boundingMapRect
        view.setVisibleMapRect(mapRect,edgePadding: UIEdgeInsets(top: 10,left: 10,bottom: 10,right: 10),animated: true)
        view.addOverlay(circle)
    }
}

解决方法

首先,您应该将 mapViewDelegate 设置在 makeUIView 而不是 updateUIView,因为 updateUIView 被调用的次数太多,您只需要设置一次委托即可。

您的问题来自这一行:

mapView.showsUserLocation = true

这意味着当你的地图被实例化时,它会自动关注你用户的位置。

func addCircle(to view: MKMapView) {

    // Lets put a defaut radius of 30 km
    let radius: Double = 30
    if !view.overlays.isEmpty { view.removeOverlays(view.overlays) }
    
    let aCircle = MKCircle(center: view.centerCoordinate,radius: radius * 1000)
    let mapRect = aCircle.boundingMapRect
    
    view.setVisibleMapRect(mapRect,edgePadding: UIEdgeInsets(top: 50,left: 50,bottom: 50,right: 50),animated: true)
    view.addOverlay(aCircle)
}

然后,在我的 MKMapViewDelegate rendererFor 中:

func mapView(_ mapView: MKMapView,rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    guard let circleOverlay = overlay as? MKCircle else {
        return MKOverlayRenderer()
    }
    let circleRenderer = MKCircleRenderer(overlay: circleOverlay)
    circleRenderer.fillColor = .blue
    circleRenderer.alpha = 0.1
    return circleRenderer
}