当前位置: 首页 > 面试题库 >

如何在Swift中创建MKCircle?

丰博
2023-03-14
问题内容

我一直在四处搜寻有关如何使用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))
        }
    })

问题答案:

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

在您的主故事板文件中,将地图工具包视图拖到故事板的场景(视图)上,并为其创建出口,在这里我创建了mapView。另外,您还希望在地图上长按时动态创建叠加层,因此将“长按手势识别器”从对象库拖动到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
    }
}


 类似资料:
  • 问题内容: 我一直在努力在Swift中创建UIAlertView,但由于某种原因,由于出现此错误,我无法正确执行该语句: 找不到接受提供的参数的’init’的重载 这是我的写法: 然后调用它,我正在使用: 截至目前,它崩溃了,我似乎无法正确理解语法。 问题答案: 从班级: //不推荐使用UIAlertView。改用 UIAlertController 和UIAlertControllerStyle

  • 我一直在Swift中创建一个UIAlertView,但由于某种原因,我无法得到正确的语句,因为我得到了以下错误: 找不到接受所提供参数的“init”的重载

  • 问题内容: 我想暂时暂停我的应用。换句话说,我希望我的应用执行代码,但是在某个时候暂停4秒钟,然后继续执行其余的代码。我怎样才能做到这一点? 我正在使用Swift。 问题答案: 如果要从UI线程调用该方法,则可以考虑使用或调度计时器,而不是进行睡眠(这会锁定您的程序)。 但是,如果您确实需要延迟当前线程: 这使用UNIX中的功能。

  • 问题内容: 在目标c中,我可以创建一个类数组并在方法中使用它 但是,swift没有“类”功能。返回类的元类型会导致错误 最后一行导致“致命错误:数组元素无法桥接到Objective-C” 如何在Swift中创建类数组? 问题答案: 显然,此问题已在Beta 3中修复,因此不再需要解决方法 我发现了一个纯粹的Swift hack: 先前的答案 我无法在Swift中以任何方式获取实例。似乎无法直接从转

  • 问题内容: 我正在尝试在文件中创建如下。 问题是我发现了问题 类型“配置”没有成员“窗口” 请让我知道如何解决该问题。 问题答案: 表示该类中有一个对象,事实并非如此。 您将需要与with 一起使用,但这无济于事,因为此窗口实际上并不代表任何现有的窗口,而且它也不是视图控制器。 因此,我建议您将要使用的实际视图控制器传递给该方法: 然后从可使用UIViewController对象的类中调用它。