如何在 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()。
为 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()
}
添加用于在长按手势识别器操作方法 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 {}
为了使代码看起来更简洁,您可以在 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
}
}
我一直在四处寻找关于如何使用 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()。
为 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() }
添加用于在长按手势识别器操作方法 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 {}
为了使代码看起来更简洁,您可以在 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
}
}