Swift - 使用MapKit显示地图,并在地图上做标记
作者:hangge | 2015-07-10 11:09
(本文代码已升级至Swift3)
1,通过mapType属性,可以设置地图的显示类型
MKMapType.standard :标准地图
MKMapType.satellite :卫星地图
MKMapType.hybrid :混合地图
2,地图显示范围的设置
MKCoordinateSpan 对象设置地图范围,其中包含两个成员 latitudeDelta 和 longtitudeDelta,这两个类型为 CLLocationDegrees(实际就是 double 类型)。
一般设置为多少纬度,1纬度约等于111千米(69英里)
3,添加标记
使用 MKPointAnnotation 对象可以在地图上任意位置添加大头针,同时还可以给这个标记添加标题和描述。
4,下面通过样例来演示
import UIKit import MapKit import CoreLocation class ViewController: UIViewController { var mainMapView: MKMapView! //定位管理器 let locationManager:CLLocationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() //使用代码创建 self.mainMapView = MKMapView(frame:self.view.frame) self.view.addSubview(self.mainMapView) //地图类型设置 - 标准地图 self.mainMapView.mapType = MKMapType.standard //创建一个MKCoordinateSpan对象,设置地图的范围(越小越精确) let latDelta = 0.05 let longDelta = 0.05 let currentLocationSpan:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta) //定义地图区域和中心坐标( //使用当前位置 //var center:CLLocation = locationManager.location.coordinate //使用自定义位置 let center:CLLocation = CLLocation(latitude: 32.029171, longitude: 118.788231) let currentRegion:MKCoordinateRegion = MKCoordinateRegion(center: center.coordinate, span: currentLocationSpan) //设置显示区域 self.mainMapView.setRegion(currentRegion, animated: true) //创建一个大头针对象 let objectAnnotation = MKPointAnnotation() //设置大头针的显示位置 objectAnnotation.coordinate = CLLocation(latitude: 32.029171, longitude: 118.788231).coordinate //设置点击大头针之后显示的标题 objectAnnotation.title = "南京夫子庙" //设置点击大头针之后显示的描述 objectAnnotation.subtitle = "南京市秦淮区秦淮河北岸中华路" //添加大头针 self.mainMapView.addAnnotation(objectAnnotation) } }
5,标记样式的修改
默认标记是一个红色的大头针。通过MKMapViewDelegate代理,我们可以自定义大头针的样式,以及点击注释视图右侧按钮样式等。
import UIKit import MapKit import CoreLocation class ViewController: UIViewController, MKMapViewDelegate { var mainMapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() //使用代码创建 self.mainMapView = MKMapView(frame:self.view.frame) self.view.addSubview(self.mainMapView) self.mainMapView.delegate = self //添加大头针等相关代码(这个同前面一样,就不再写了) //....... } //自定义大头针样式 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if annotation is MKUserLocation { return nil } let reuserId = "pin" var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuserId) as? MKPinAnnotationView if pinView == nil { //创建一个大头针视图 pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuserId) pinView?.canShowCallout = true pinView?.animatesDrop = true //设置大头针颜色 pinView?.pinTintColor = UIColor.green //设置大头针点击注释视图的右侧按钮样式 pinView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) }else{ pinView?.annotation = annotation } return pinView } }
6,地图代理 - MKMapViewDelegate中所有代理方法
MKMapViewDelegate除了可以设置大头针样式,注释视图点击响应等。还可以在地图相关事件发生时(比如缩放,地图加载,位置跟踪等),触发相应的方法。
import UIKit import MapKit import CoreLocation class ViewController: UIViewController, MKMapViewDelegate { var mainMapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() //使用代码创建 self.mainMapView = MKMapView(frame:self.view.frame) self.view.addSubview(self.mainMapView) self.mainMapView.delegate = self } func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) { print("地图缩放级别发送改变时") } func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) { print("地图缩放完毕触法") } func mapViewWillStartLoadingMap(_ mapView: MKMapView) { print("开始加载地图") } func mapViewDidFinishLoadingMap(_ mapView: MKMapView) { print("地图加载结束") } func mapViewDidFailLoadingMap(_ mapView: MKMapView, withError error: Error) { print("地图加载失败") } func mapViewWillStartRenderingMap(_ mapView: MKMapView) { print("开始渲染下载的地图块") } func mapViewDidFinishRenderingMap(_ mapView: MKMapView, fullyRendered: Bool) { print("渲染下载的地图结束时调用") } func mapViewWillStartLocatingUser(_ mapView: MKMapView) { print("正在跟踪用户的位置") } func mapViewDidStopLocatingUser(_ mapView: MKMapView) { print("停止跟踪用户的位置") } func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { print("更新用户的位置") } func mapView(_ mapView: MKMapView, didFailToLocateUserWithError error: Error) { print("跟踪用户的位置失败") } func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) { print("改变UserTrackingMode") } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { print("设置overlay的渲染") return MKPolylineRenderer() } private func mapView(mapView: MKMapView, didAddOverlayRenderers renderers: [MKOverlayRenderer]) { print("地图上加了overlayRenderers后调用") } /*** 下面是大头针标注相关 *****/ func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) { print("添加注释视图") } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { print("点击注释视图按钮") } func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { print("点击大头针注释视图") } func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) { print("取消点击大头针注释视图") } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) { print("移动annotation位置时调用") } }
全部评论(8)
航哥,怎么能通过按钮改变当前地图的级别啊?或者直接获取到当前地图的缩放级别?
站长回复:没有直接设置缩放级别的办法,不过我们可以根据缩放级别计算出对应的显示区域,然后将地图设置为这个显示区域。
航哥,自定义大头针没有应用到是什么原因啊?
站长回复:那就奇怪了,我又测试了下大头针确实是可以显示的啊。你运行的是我文章里的代码吗?还是有修改了经纬度坐标或者其他地方。
你好!在跑代码的时候viewDidLoad一直报错啊,说是invalid redeclaration of “viewDidLoad"
站长回复:我测试了下是没问题的啊?
航哥!这个地图运行出来的全是英文的,可以在哪个部分设置为中文啊
站长回复:地图是随设备语言的,你检查下系统环境语言是不是中文。
初学者,哥,我想知道,这个代码实现的地图在手机上是全屏,而不是我模块(mapkit)的大小,这个怎么弄?
站长回复:MKMapView初始化的时候可以通过frame属性设置需要显示的位置和尺寸。
//使用当前位置
//var center:CLLocation = locationManager.location.coordinate
hangge这里有错误,上面的第一段代码
站长回复:本文讲的是根据预置的经纬度坐标来标注,这个与本文无关所以注释掉的。你可以删掉,不够用管他。如果要获取当前位置不是这样获取的。
请问下航哥,为什么我的地图在定位的时候经纬度只显示在(0,0)位置,靠近非洲的海岸?
站长回复:这个情况我还没遇到过,暂时帮不上你了。
大头针右侧按钮怎么触发方法啊
站长回复:使用MKMapViewDelegate的代理方法(文章第6点)
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {println("点击注释视图按钮")}