打开系统自带地图的导航,必需要告诉自带的地图起始点和目的地,自带的地图又不会本身知道你想怎么走。程序员
咱们的思路大体上是:获取咱们想要导航的起始点和目的地,经过反地址编码得到两个地址的地理信息(地图总归不能本身根据汉字就知道该怎么作的吧),将地理信息封装或则不封装(假设咱们并不知道要不要封装,作以前谁都不会,这是确定的)传递给自带地图(传递的方法如今假设还不知道,后面会有讲到)。函数
首先搭建咱们界面,这个步骤繁琐而简单,对于老程序员或许不屑于为之,可是能把简单的事情作好就是不简单,再怎么熟悉你能保证每次作都不会出错吗,因此必定要认真对待每一步。编码
必需要输入起始地和目的地吧,那就拖两个textView进去。再拖一个导航开始的Button进去,将这三个控件连线到相应的控制器。有时,为了迎合主流地图软件傻瓜式的操做,咱们在其实地点的输入框右侧加一个设置"起始点"为"当前位置"的按钮。atom
造成的界面和代码以下:spa
下面是拖线以后的代码:code
@property (weak, nonatomic) IBOutlet UITextField *startField;//其实地点的输入框 @property (weak, nonatomic) IBOutlet UITextField *endField;//目的地的输入框 - (IBAction)current;//(右侧“current“按钮操做)获取当前位置 - (IBAction)startNavigation;//”开始导航“按钮操做
假设没有这个解析器,你告诉我该怎么作,没思路是吗,因此我告诉你,咱们须要这个解析器。对象
有了界面以后,第二部就是解析出"汉字"中的"地理信息",只有这些特殊的"地理信息",地图才可以识别,传给它汉字它要是能识别,就没人作导航了。blog
不知道你不知不知道,从"汉字"获取地理信息,叫作"反地理编码",固然还有"地理编码"(知道地理信息,其实就是经度和纬度两个值,通过编码器获取地名等一些关于编码出的地点的其余信息。如需更多信息,请参照其余人的文章).string
咱们提到编码器,其实就是这个:it
@property (strong, nonatomic) CLGeocoder *geocoder;
为了保持它不被销毁,设置为strong。
咱们让它成为懒加载对象
1 - (CLGeocoder *)geocoder 2 { 3 if (_geocoder == nil) { 4 self.geocoder = [[CLGeocoder alloc] init]; 5 } 6 return _geocoder; 7 }
那如今编码器也有了,就能够获取地理信息了。
这段比较长,可能难理解,可是代码很顺畅,好好看。别问我为何很差好一句一句写,累了,手疼
下面是代码,无码无真相:
1 - (IBAction)startNavigation {//这个函数就是咱们"开始导航"的操做函数
2 [self.geocoder geocodeAddressString:self.endField.text completionHandler:^(NSArray *placemarks, NSError *error) {//编码器拿到string类型的地名进行反编码,完了以后调用completionhandler块代码,传入反编码的结果NSArray和错误信息 3 if (error) return;//若是发编码有错误,后面也就不用进行了,直接返回 4
5 CLPlacemark *placemark = [placemarks firstObject];//可以到这里说明没有错误,那咱们取出众多结果中最有可信度的(也就是第一个,人们习惯把最好的放在前面),先不要管CLPlacemark是什么,想知道的话百度下就知道了。 6 //下面咱们封装得到的地理结果,看得出咱们至获取了目的地的地理信息,那是由于咱们默认使用当前位置,也就是你输入了起始地咱们也没用,你想用能够根据代码本身编写
7 MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];//有简单的方法把当前位置封装到MKMapItem中 8 MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithPlacemark:placemark]];//地理信息"placemark"封装到"MKPlacemark"中,"MKPlacemark"被封装到"MKMapItem"中,还真是封装了好几层,没办法,mapView只识别"MKMapItem" 9 //下面创建一个可变字典,选择你要对自带地图所作的操做属性,讲这个字典传给地图就好了,还真是神奇
10 NSMutableDictionary *options = [NSMutableDictionary dictionary]; 11 options[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving;//自驾模式 12 options[MKLaunchOptionsShowsTrafficKey] = @YES;//开启导航 13 [MKMapItem openMapsWithItems:@[currentLocation, toLocation] launchOptions:options]; 14 }];//withItems看得出地图只是别MKMapItem对象。最后只用了一句话打开地图,他妈的只用了一句话。 15 }
其余的代码文件压根没动过,只在ViewController和main.storyboard里面进行编码和拖拽了
// // ViewController.m // 预习-05-苹果自带地图 #import "ViewController.h" #import <CoreLocation/CoreLocation.h> #import <MapKit/MapKit.h> @interface ViewController () @property (strong, nonatomic) CLGeocoder *geocoder; @property (weak, nonatomic) IBOutlet UITextField *startField; @property (weak, nonatomic) IBOutlet UITextField *endField; - (IBAction)current; - (IBAction)startNavigation; @end @implementation ViewController - (CLGeocoder *)geocoder { if (_geocoder == nil) { self.geocoder = [[CLGeocoder alloc] init]; } return _geocoder; } - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)current { } - (IBAction)startNavigation { [self.geocoder geocodeAddressString:self.endField.text completionHandler:^(NSArray *placemarks, NSError *error) { if (error) return; CLPlacemark *placemark = [placemarks firstObject]; MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation]; MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithPlacemark:placemark]]; NSMutableDictionary *options = [NSMutableDictionary dictionary]; options[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving; options[MKLaunchOptionsShowsTrafficKey] = @YES; [MKMapItem openMapsWithItems:@[currentLocation, toLocation] launchOptions:options]; }]; } @end