【问题标题】:How to create MKCircle in Swift?如何在 Swift 中创建 MKCircle?
【发布时间】:2017-07-13 19:00:45
【问题描述】:

我一直在四处寻找关于如何使用 Swift 2.0 为 MapView 制作 MKCircle 注释的很好的解释,但我似乎找不到足够的解释。有人可以发布一些示例代码来展示如何创建 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))
        }
    })

【问题讨论】:

    标签: swift mkmapview


    【解决方案1】:

    首先您需要将 MKMapViewDelegate 添加到类定义中。

     mapView.delegate = self 
    

    在 viewDidLoad 中将地图委托设置为 self。

    设置注释

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

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

    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 才能编译

    【讨论】:

    • 感谢 Animal 的帮助,我已经成功了。
    • 很好的答案!顺便说一句,现在您不能在必须返回值的函数中(仅)有条件返回。并且 rendererForOverlay 强制你返回一个非空值。所以我不知道如果我有一个未知的覆盖我能做什么。我想那会是一场崩溃。
    • default > 最后return MKOverlayRenderer(overlay: overlay)
    • @Moriya 嘿,我遇到了这个解决方案的问题,每次用户位置移动时,叠加层都会相互重叠,我只想一次显示一个。你能帮帮我吗?
    【解决方案2】:

    将展示有关如何使用带有 xcode 8.3.3 的 swift 3 在地图视图上创建圆形叠加层的逐步方法

    在您的主情节提要文件中,将地图套件视图拖到情节提要的场景(视图)并为其创建插座,这里我创建了 mapView。此外,您还想在地图上长按时动态创建叠加层,因此将 Long Press Gesture Recognizer 从对象库拖到 mapView 上,然后为其创建操作方法,这里我创建了 addRegion() 相同的方法。

    1. 为 CLLocationManager 类创建一个全局常量,以便在每个函数中都可以访问它。在你的 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. 为了使代码看起来更简洁,您可以在类结束的最后一个大括号之后创建扩展。一个扩展包含 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
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 一个描述性的答案如此有用
      猜你喜欢
      • 1970-01-01
      • 2014-11-24
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2019-02-24
      • 2014-08-18
      • 1970-01-01
      • 2018-02-22
      相关资源
      最近更新 更多