0.起步 项目版本有内置地图的开发需求,因此做了一波技术预研。 0.1 MapKit MapKit是苹果的内置地图框架,目前在国内使用的是高德地图提供的服务,所以即便是内置地图,也能提供较为详细的地图信息。 导入:

#import <MapKit/MapKit.h>
复制代码

0.2 CoreLocation.framework CoreLocation是苹果提供的导航+定位服务框架,我们在后续开发中需要依仗他来进行地图导航定位开发。 导入:

#import <CoreLocation/CoreLocation.h>
复制代码

1.内置地图开发

1.1 MapView 为了实现上图中的地图页面,我们需要通过MapKit提供的MapView来导入地图。 在Capabilities中打开Maps的权限

在StoryBoard中拖入MapView

为MapView添加代理,并且指定第一次启动时候加载的地图方位,例如经纬度为(24.489224794270353f,118.18014079685172f)(6号楼的经纬度)

    self.mapView.delegate = self;self.mapView.mapType = MKMapTypeMutedStandard;self.mapView.showsUserLocation = YES;self.mapView.userTrackingMode = MKUserTrackingModeFollow;//CLLocationCoordinate2DMake:参数: 维度、经度、南北方宽度(km)、东西方宽度(km)double lat = 24.489224794270353f;double lon = 118.18014079685172f;[self.mapView setRegion:MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(lat , lon), 300, 194)animated:YES];
复制代码

以上代码中,我们看到self.mapView.showsUserLocation = YES;这一步看字面意思是要在地图上显示用户的地理位置。 但在实际的场景中,MapKit本身不提供导航、定位功能,仅提供地图信息。所以在此我们需要再引入CoreLocation来提供用户的位置信息。

1.2 定位服务 CLLocationManager能够为我们提供导航定位所需的一些用户权限支持,在开启服务之前,我们需要跟用户获取相关的系统权限。

    if (nil == _locationManager)_locationManager = [[CLLocationManager alloc] init];_locationManager.delegate = self;_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;if([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){[_locationManager requestWhenInUseAuthorization];}if(![CLLocationManager locationServicesEnabled]){NSLog(@"请开启定位:设置 > 隐私 > 位置 > 定位服务");}
// 持续使用定位服务if([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {[_locationManager requestAlwaysAuthorization]; // 永久授权[_locationManager requestWhenInUseAuthorization]; //使用中授权}// 方位服务if ([CLLocationManager headingAvailable]){_locationManager.headingFilter = 5;[_locationManager startUpdatingHeading];}
[_locationManager startUpdatingLocation];
复制代码

在info.plist中我们需要添加:

Privacy - Location When In Use Usage Description
复制代码

当我们调用上部分代码后之后,我们便能在地图上看到我们的定位了。 如果一眼看不到,记得拖一拖地图,并且确定Wifi没连接代理VPN。(我曾在洛杉矶看到我的位置)

1.3导航服务 关于导航,我们可以提供的便是我们当前MapKit中的线路绘制,或者调用系统的地图服务app,或者调用百度地图、高德地图这些三方应用。 为了偷懒,我仅仅介绍MapKit绘制地图和调用系统地图App。 系统内置地图导航App:

- (void)navByVender {CLLocation *begin = [[CLLocation alloc] initWithLatitude:[[NSNumber numberWithFloat:self.myPlace.latitude] floatValue]longitude:[[NSNumber numberWithFloat:self.myPlace.longitude] floatValue]];[self.geocoder reverseGeocodeLocation:begin completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {__block CLPlacemark * beginPlace = [placemarks firstObject];CLLocation *end = [[CLLocation alloc] initWithLatitude:[[NSNumber numberWithFloat:self.finishPlace.latitude] floatValue]longitude:[[NSNumber numberWithFloat:self.finishPlace.longitude] floatValue]];[self.geocoder reverseGeocodeLocation:end completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {if(error) {                NSLog(@"Error Info %@",error.userInfo);} else {CLPlacemark * endPlace = [placemarks firstObject];MKMapItem * beginItem = [[MKMapItem alloc] initWithPlacemark:beginPlace];MKMapItem * endItem = [[MKMapItem alloc] initWithPlacemark:endPlace];NSString * directionsMode;                switch (self.navType) {case 0:directionsMode = MKLaunchOptionsDirectionsModeWalking;break;case 1:directionsMode = MKLaunchOptionsDirectionsModeDriving;break;case 2:directionsMode = MKLaunchOptionsDirectionsModeTransit;break;default:directionsMode = MKLaunchOptionsDirectionsModeWalking;break;}
NSDictionary *launchDic = @{//范围MKLaunchOptionsMapSpanKey : @(50000),// 设置导航模式参数MKLaunchOptionsDirectionsModeKey : directionsMode,// 设置地图类型MKLaunchOptionsMapTypeKey : @(MKMapTypeStandard),// 设置是否显示交通MKLaunchOptionsShowsTrafficKey : @(YES),                                            };[MKMapItem openMapsWithItems:@[beginItem, endItem] launchOptions:launchDic];}}];}];
}
复制代码

导航发起之前,我们需要准备好两个坐标,以上代码中,我把用户自身的地址作为Begin地点,把地图正中央作为目的地的坐标进行导航。(反正你传两个坐标就对了)

//地理编码方法
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
// 反地理编码方法- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
复制代码

地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等) 反地理编码:根据给定的经纬度,获得具体的位置信息 我们需要reverseGeocodeLocation来做地图的反地理编码操作,这样我们传入的地理坐标才被识别为地理位置信息。

[MKMapItem openMapsWithItems:@[beginItem, endItem] launchOptions:launchDic];
复制代码

这一处代码,变回唤起系统内置的地图导航功能。

内置MapKit可绘制的导航方案:

MKPlacemark *fromPlacemark = [[MKPlacemark alloc] initWithCoordinate:self.myPlace addressDictionary:nil];MKPlacemark *toPlacemark   = [[MKPlacemark alloc] initWithCoordinate:self.finishPlace addressDictionary:nil];MKMapItem *fromItem = [[MKMapItem alloc] initWithPlacemark:fromPlacemark];MKMapItem *toItem   = [[MKMapItem alloc] initWithPlacemark:toPlacemark];- (void)findDirectionsFrom:(MKMapItem *)from to:(MKMapItem *)to{MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];request.source = from;request.destination = to;request.transportType = MKDirectionsTransportTypeWalking;MKDirections *directions = [[MKDirections alloc] initWithRequest:request];//ios7获取绘制路线的路径方法[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {if (error) {NSLog(@"Error info:%@", error.userInfo[@"NSLocalizedFailureReason"]);}else {for (MKRoute *route in response.routes) {//                MKRoute *route = response.routes[0];for(id<MKOverlay> overLay in self.mapView.overlays) {[self.mapView removeOverlay:overLay];}                [self.mapView addOverlay:route.polyline level:0];double lat = self.mapView.region.center.latitude;double lon = self.mapView.region.center.longitude;double latDelta = self.mapView.region.span.latitudeDelta * 100000;double lonDelta = self.mapView.region.span.longitudeDelta * 100000;if(_firstStarNav) {_firstStarNav = NO;[self.mapView setRegion:MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(lat , lon), 200, 126)animated:YES];}}}}];
}
复制代码

在以上方法后,我们可以在以下一个代理中获得一套地图路线,我们可以通过以下方式,将绘制到地图上的线路定制化。

- (MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id)overlay {MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];renderer.lineWidth = 5;renderer.strokeColor = HEX_RGBA(0xf26f5f, 1);return renderer;
}
复制代码

这里补充一下,在地图上显示的各种线段绘制之类的呃,都是要在overlay层进行表示的。 我们可控制的线段的宽度、颜色、延续的拐角光滑度、线头是否圆角。

1.4 地图中的元素定制 在地图中我们可以对一些UI方案进行定制。

我们能够进行完全定制的,是在地图上的Pin图钉。

我们可以在一下方法中,对Annotation进行修改。(这个方法堪比 table的那个cellForRow)

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
复制代码

在图钉上方弹出的苹果称之为CalloutAccessoryView,这里我们可以修改的便是左右部分的View,此处可以添加Button或者UIImageView。 我们在这个方法中,还会获取到用户个人定位服务下自己的图钉信息。此处也可以定制。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{MKAnnotationView* aView;if ([annotation isKindOfClass:[MKUserLocation class]]) {self.myPlace = annotation.coordinate;return nil;} else if([annotation isKindOfClass:[MyPinAnnotation class]]) {aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MyPinAnnotation"];aView.canShowCallout = YES;aView.image = [UIImage imageNamed:@"pin"];aView.frame = CGRectMake(0, 0, 50, 50);UIImageView *myCustomImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon"]];myCustomImage.frame = CGRectMake(0, 0, 50, 50);aView.leftCalloutAccessoryView = myCustomImage;     MapMarkBtn *rightButton = [[MapMarkBtn alloc] initWithFrame:CGRectMake(0, 0, 80, 50)];rightButton.coordinate = annotation.coordinate;rightButton.backgroundColor = [UIColor grayColor];[rightButton setTitle:@"到这里去" forState:UIControlStateNormal];[rightButton addTarget:self action:@selector(gotoPlace:) forControlEvents:UIControlEventTouchUpInside];aView.rightCalloutAccessoryView = rightButton;}else  {aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MKPointAnnotation"];aView.canShowCallout = YES;aView.image = [UIImage imageNamed:@"pin"];aView.frame = CGRectMake(0, 0, 50, 50);   }return aView;
}复制代码

多说无益,附上地图功能的Demo地址:

https://github.com/filelife/FLMapKit.git
复制代码

祝:各位看官身体健康 此致敬礼!

iOS内置地图导航开发指南相关推荐

  1. 微信公众号内置地图开发ios苹果不显示地图

    在微信开发中遇到了安卓正常显示内置地图,但是ios苹果系统不显示,经过排查是因为ios系统调用网页时的经度和纬度必须使用Number类型的,但是安卓的可以. wx.config({debug: fal ...

  2. Blazor 路由及导航开发指南

    翻译自 Waqas Anwar 2021年4月2日的文章 <A Developer's Guide To Blazor Routing and Navigation> [1] 检查传入的请 ...

  3. 微信小程序----wx.openLocation(OBJECT) 使用微信内置地图查看位置

    WXRUI体验二维码 如果文章对你有帮助的话,请打开微信扫一下二维码,点击一下广告,支持一下作者!谢谢! 开发场景 已知地点的经纬度,期望在打开的地图进行标注位置和进行开车.徒步.公交.骑行等的路线规 ...

  4. 微信JS接口 分享到朋友圈 分享给朋友 分享到QQ 拍照或从手机相册中选图 识别音频并返回识别结果 使用微信内置地图查看位置

    微信JS接口 微信JS接口 分享到朋友圈 分享给朋友 分享到QQ 拍照或从手机相册中选图 识别音频并返回识别结果 使用微信内置地图查看位置 来源:http://www.cnblogs.com/txw1 ...

  5. weixin公众号页面返回上一层_微信公众号jssdk打开内置地图点击返回会回到之前页面,怎么退出页面...

    问题描述 在使用公众号jssdk过程中,用户需求点击公众号菜单微信内置地图打开指定地点. 暂用实现过程为 用户打开空白页面 空白页面wx.config wx.openLocation打开内置地图 问题 ...

  6. 微信小程序----使用微信内置地图查看位置wx.openLocation(Object object)

    本博客为博主原创,若需转载请联系博主征得同意.有不当之处,敬请指出,共同进步,谢谢! 使用微信内置地图查看位置wx.openLocation(Object object) 1.官方文档 wx.open ...

  7. 微信小程序自带地图_微信小程序获取当前位置并调用微信内置地图打开

    图示: index.wxml 定位 index.js //index.js //获取应用实例 const app = getApp() Page({ data: { }, map:function() ...

  8. 微信JS-SDK 分享到朋友圈 分享给朋友 分享到QQ 拍照或从手机相册中选图 识别音频并返回识别结果 使用微信内置地图查看位置

    微信JS-SDK 分享到朋友圈 分享给朋友 分享到QQ 拍照或从手机相册中选图 识别音频并返回识别结果 使用微信内置地图查看位置 一.JS部分 wx.ready(function () {// 1 判 ...

  9. 微信小程序获取当前位置并调用微信内置地图打开

    图示: index.wxml <!--index.wxml--> <button bindtap="map">定位</button> //ind ...

最新文章

  1. Azure云端部署Exchange 2016双数据中心—Part6(DAG切换测试)
  2. 百度机器阅读理解比赛赛后总结
  3. Effective Java~23. 类层次优于标签类
  4. Spark源码分析之DiskBlockMangaer分析
  5. SAP License:你熟悉SAP的统驭科目吗?
  6. mysql的粒度_MySQL中权限的粒度和时效性
  7. 快手小视频批量下载高清无水印软件 快手短视频批量下载高清无水印软件
  8. iOS性能优化之内存篇
  9. 【ROS】编译软件包packages遇到进度缓慢或卡死,使用swap
  10. 会计信息质量可靠性的案例_浅谈会计信息可靠性(一)
  11. mysql 实例结构体_C语言结构体实例-创建兔子
  12. AJP:纵向研究:抑郁症青年在当前期和累积期的奖赏系统的功能障碍具有不同的神经基础
  13. 基于centos8部署nextcloud+onlyoffice----2021-07-16
  14. 利用stm32f103c8t6实现对WS2812的控制(从硬件出发)
  15. springboot整合liquibase(补充)
  16. BT下载到底是什么意思啊?
  17. c#中将一个实体类复制到另一个实体类
  18. Java获取当前时间前24小时时间
  19. 云终端和瘦客户机的区别
  20. lamp +discuz+wordpress+phpmyadmin实例安装详解

热门文章

  1. 照片做成视频的软件手机上用照片做成视频
  2. 共享充电宝行业面临狼来了,新进入者疑似滥用垄断权力
  3. python中argv的使用_python中使用sys.argv命令行参数
  4. @Documented:
  5. python-pyperclip模块
  6. 提高设计的审美,看这里
  7. 水晶苍蝇拍:有关财报分析必要性及方法的讨论
  8. 有感于开源软件发布的情怀
  9. sql语句批量清空表数据
  10. Ubuntu系统下的shell 命令