在程序中使用代码打开苹果自带的地图并实现导航

思路分析

打开系统自带地图的导航,必须要告诉自带的地图起始点和目的地,自带的地图又不会自己知道你想怎么走。

我们的思路大致上是:获取我们想要导航的起始点和目的地,通过反地址编码获得两个地址的地理信息(地图总归不能自己根据汉字就知道该怎么做的吧),将地理信息封装或则不封装(假设我们并不知道要不要封装,做之前谁都不会,这是肯定的)传递给自带地图(传递的方法现在假设还不知道,后面会有讲到)。

开始我们的编码吧!

1.搭建界面

  首先搭建我们界面,这个步骤繁琐而简单,对于老程序员或许不屑于为之,但是能把简单的事情做好就是不简单,再怎么熟悉你能保证每次做都不会出错吗,所以一定要认真对待每一步。

  必须要输入起始地和目的地吧,那就拖两个textView进去。再拖一个导航开始的Button进去,将这三个控件连线到相应的控制器。有时,为了迎合主流地图软件傻瓜式的操作,我们在其实地点的输入框右侧加一个设置"起始点"为"当前位置"的按钮。

  形成的界面和代码如下:

下面是拖线之后的代码:

@property (weak, nonatomic) IBOutlet UITextField *startField;//其实地点的输入框
@property (weak, nonatomic) IBOutlet UITextField *endField;//目的地的输入框
- (IBAction)current;//(右侧“current“按钮操作)获取当前位置
- (IBAction)startNavigation;//”开始导航“按钮操作

2. 创建解析器

  假设没有这个解析器,你告诉我该怎么做,没思路是吗,所以我告诉你,我们需要这个解析器。

  有了界面之后,第二部就是解析出"汉字"中的"地理信息",只有这些特殊的"地理信息",地图才能够识别,传给它汉字它要是能识别,就没人做导航了。

  不知道你不知不知道,从"汉字"获取地理信息,叫做"反地理编码",当然还有"地理编码"(知道地理信息,其实就是经度和纬度两个值,经过编码器获取地名等一些关于编码出的地点的其他信息。如需更多信息,请参照其他人的文章).

  我们提到编码器,其实就是这个:

@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 }

3. 获取地理信息,打开地图

   那现在编码器也有了,就可以获取地理信息了。

  这段比较长,可能难理解,但是代码很顺畅,好好看。别问我为什么不好好一句一句写,累了,手疼

  下面是代码,无码无真相:

 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

不服者请留言 !!!

 

转载于:https://www.cnblogs.com/angryli/p/4499030.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值