如何在 Swift 中创建 MKCircle?

How to create MKCircle in Swift?

我一直在四处寻找关于如何使用 Swift 2.0 为 MapView 制作 MKCircle 注释的良好解释,但我似乎找不到足够的解释。有人可以 post 一些示例代码来展示如何创建 MKCircle 注释吗?这是我用来制作地图和获取坐标的代码。

let address = self.location

let geocoder = CLGeocoder()

    geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in
        if((error) != nil){
            print("Error", error)
        }
        if let placemark = placemarks?.first {
            let coordinates:CLLocationCoordinate2D = placemark.location!.coordinate

            self.locationCoordinates = coordinates
            let span = MKCoordinateSpanMake(0.005, 0.005)
            let region = MKCoordinateRegion(center: self.locationCoordinates, span: span)
            self.CIMap.setRegion(region, animated: true)

            let annotation = MKPointAnnotation()
            annotation.coordinate = self.locationCoordinates
            self.CIMap.addAnnotation(annotation)

            self.CIMap.layer.cornerRadius = 10.0

            self.CIMap.addOverlay(MKCircle(centerCoordinate: self.locationCoordinates, radius: 1000))
        }
    })

叠加只是一组数字。在地图视图中可见的是 叠加渲染器 。您必须实施 mapView:rendererForOverlay: 来提供叠加渲染器;否则,你什么也看不到。

首先您需要将 MKMapViewDelegate 添加到 class 防御中。

 mapView.delegate = self 

在您的 viewDidLoad 中将地图委托设置为自己。

设置注释

mapView.addOverlay(MKCircle(centerCoordinate: CLLocationCoordinate2D, radius: CLLocationDistance))

现在应该在 mapViews 委托中调用 mapView rendererForOverlay,然后您就可以绘制它了

func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
    if let overlay = overlay as? MKCircle {
        let circleRenderer = MKCircleRenderer(circle: overlay)
        circleRenderer.fillColor = UIColor.blueColor()
        return circleRenderer
    }
}

此外,您需要导入 MapKit 才能全部编译

将展示如何使用 swift 3 和 xcode 8.3.3

在地图视图上创建圆形叠加层的逐步方法

在您的主故事板文件中,将地图工具包视图拖到故事板的场景(视图)上并为其创建出口,这里我创建了 mapView。此外,您还想在地图上长按时动态创建叠加层,因此将长按手势识别器从对象库拖到 mapView 上,然后为其创建操作方法,这里我为其创建了 addRegion()。

  1. 为 CLLocationManager class 创建一个全局常量,以便它可以在每个函数中访问。并在您的 viewDidLoad 方法中,添加一些代码以获取用户的授权。

        import UIKit  
        import MapKit
    
        class ViewController: UIViewController {
    
    
            @IBOutlet var mapView: MKMapView!
            let locationManager = CLLocationManager()
    
        override func viewDidLoad() {  
                super.viewDidLoad()
    
                locationManager.delegate = self
                locationManager.requestAlwaysAuthorization()
                locationManager.requestWhenInUseAuthorization()
                locationManager.desiredAccuracy = kCLLocationAccuracyBest
                locationManager.startUpdatingLocation()
    
            }
    
  2. 添加用于在长按手势识别器操作方法 addRegion() 中执行长按手势识别器时生成圆形区域的代码。

        @IBAction func addRegion(_ sender: Any) {  
                print("addregion pressed")  
                guard let longPress = sender as? UILongPressGestureRecognizer else {return}
    
                let touchLocation = longPress.location(in: mapView)
                let coordinates = mapView.convert(touchLocation, toCoordinateFrom: mapView)
                let region = CLCircularRegion(center: coordinates, radius: 5000, identifier: "geofence")
                mapView.removeOverlays(mapView.overlays)
                locationManager.startMonitoring(for: region)
                let circle = MKCircle(center: coordinates, radius: region.radius)
                mapView.add(circle)
    
            }
    

在地图上渲染圆圈之前,您仍然不会在地图上看到圆圈。为此,您需要实现 mapviewdelegate 的委托。

        func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {}
  1. 为了使代码看起来更简洁,您可以在 class 结束的最后一个大括号之后创建扩展。一个扩展包含 CLLocationManagerDelegate 的代码,另一个包含 MKMapViewDelegate 的代码。

        extension ViewController: CLLocationManagerDelegate {
            func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
                locationManager.stopUpdatingLocation()
                mapView.showsUserLocation = true
            }
        }
    

您应该在委托方法中调用 locationManager.stopUpdatingLocation(),这样您的电池就不会耗尽。

        extension ViewController: MKMapViewDelegate {
            func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
                guard let circelOverLay = overlay as? MKCircle else {return MKOverlayRenderer()}

                let circleRenderer = MKCircleRenderer(circle: circelOverLay)
                circleRenderer.strokeColor = .blue
                circleRenderer.fillColor = .blue
                circleRenderer.alpha = 0.2
                return circleRenderer
            }
        }

这里我们在屏幕上制作实际的圆圈。

最终代码应如下所示。

import UIKit
import MapKit

class ViewController: UIViewController {


    @IBOutlet var mapView: MKMapView!
    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()

    }

    // MARK: Long Press Gesture Recognizer Action Method

    @IBAction func addRegion(_ sender: Any) {
        print("addregion pressed")
        guard let longPress = sender as? UILongPressGestureRecognizer else {return}

        let touchLocation = longPress.location(in: mapView)
        let coordinates = mapView.convert(touchLocation, toCoordinateFrom: mapView)
        let region = CLCircularRegion(center: coordinates, radius: 5000, identifier: "geofence")
        mapView.removeOverlays(mapView.overlays)
        locationManager.startMonitoring(for: region)
        let circle = MKCircle(center: coordinates, radius: region.radius)
        mapView.add(circle)

    }

}

extension ViewController: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locationManager.stopUpdatingLocation()
        mapView.showsUserLocation = true
    }
}

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        guard let circelOverLay = overlay as? MKCircle else {return MKOverlayRenderer()}

        let circleRenderer = MKCircleRenderer(circle: circelOverLay)
        circleRenderer.strokeColor = .blue
        circleRenderer.fillColor = .blue
        circleRenderer.alpha = 0.2
        return circleRenderer
    }
}