公司最近有个需求,要开发国际版的地图,接入谷歌步骤又太麻烦,刚好在学swift,写了一个基于MapKit的地图定位和轨迹绘制的demo。
目前iOS各类系统占比,iOS10以上的设备占99%以上,所以在本篇文章中不考虑iOS10以下的设备。
授权
首先是系统授权使用地图定位的功能,需要在项目的info.plish中同时加入NSLocationWhenInUseUsageDescription、NSLocationAlwaysUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription。
然后在项目的Singing & Capabilities中加入Maps,已告知苹果使用了MapKit
WechatIMG2.png
在做完以上处理后,可以在实际代码中添加授权后的一些逻辑处理
// 判断当前定位是否可用,不可用弹窗提示
if !CLLocationManager.locationServicesEnabled() {
print("设置打开定位授权")
}
if self.locationManager.responds(to: NSSelectorFromString("requestWhenInUseAuthorization")) {
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
}
添加MKMapView以及CLLocationManager
在头文件中导入MapKit,并初始化MKMapView以及定位控制器CLLocationManager,并实现MKMapViewDelegate、CLLocationManagerDelegate的代理方法
self.mapView = MKMapView.init(frame: CGRect.init(x: 0, y: 64, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
self.mapView.delegate = self
// 设置地图初始化时跟随用户缩放
self.mapView.userTrackingMode = MKUserTrackingMode.follow
self.view.addSubview(self.mapView)
// 显示用户当前位置
self.mapView.showsUserLocation = true
self.locationManager = CLLocationManager.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
这个demo中主要使用的代理有
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// 绘制运动轨迹
return MKPolylineRenderer.init()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
// 改变授权状态
print("\(#function)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
// 定位失败
print("\(#function)")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// 定位成功
print("\(#function)")
}
因为没有后台数据支持,所以在定位成功拿到了自身坐标后,在循环遍历制造出了一组直线数据,然后通过MKPolyline添加到MapView上
if self.arrayCoord.count == 0 {
// 当传入数据为空时,模拟数据绘出轨迹
for i in 0...30 {
let coord:CLLocationCoordinate2D! = CLLocationCoordinate2D.init(latitude: self.mineCoord.latitude + Double(i), longitude: self.mineCoord.longitude + Double(i))
self.arrayCoord.append(coord)
}
}
let polyLine:MKPolyline = MKPolyline.init(coordinates: self.arrayCoord, count: self.arrayCoord.count)
self.mapView.addOverlay(polyLine)
数据准备好,地图也添加上,最后剩下把我们虚假的运动轨迹添加上去
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// 根据添加的polyline数组,绘出对应的路线图
let renderer:MKPolylineRenderer! = MKPolylineRenderer.init(overlay: overlay)
renderer.strokeColor = UIColor.blue
}
福利来了,可能我们绘出的轨迹路线颜色单一,并不是产品想要的五彩斑斓的黑,github有位大佬
]提供了一个便利的方案去渲染绘制的轨迹曲线。在mapView的代理方法中返回GradientPathRenderer对象
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// 根据添加的polyline数组,绘出对应的路线图
// let renderer:MKPolylineRenderer! = MKPolylineRenderer.init(overlay: overlay)
// renderer.strokeColor = UIColor.blue
// 设置多种颜色的路线图
if let overlay = overlay as? MKPolyline {
/// define a list of colors you want in your gradient
let gradientColors = [UIColor.green, UIColor.blue, UIColor.yellow, UIColor.red]
/// Initialise a GradientPathRenderer with the colors
let polylineRenderer = GradientPathRenderer(polyline: overlay, colors: gradientColors)
/// set a linewidth
polylineRenderer.lineWidth = 7
return polylineRenderer
}
return MKPolylineRenderer.init()
}
到这里,我们就已经绘出了想要的轨迹路线
WechatIMG3.jpeg
网友评论