代码地址如下:
http://www.demodashi.com/demo/11682.html

这篇文章还是翻译自raywenderlich,用Objective-C改写了代码。没有逐字翻译,如有错漏,请指出。原文地址在这里。

1 概述

MapKit是iOS提供的一个很便捷的API,旨在帮助我们快速开发地理位置相关的应用。在这篇博客中涉及的地方叫Honolulu,是美国的一个城市,中文名是檀香山,是美国夏威夷州首府和港口城市。我第一次听说檀香山应该是在历史书上,似乎跟孙中山先生相关,这里暂时按下不表。

本文的例子中我们要添加一个地图到APP中,然后通过经纬度定位到一个指定的位置,通过大头针的形式来展示定位,点击大头针会显示位置的一些信息。我们可以设置大头针的颜色,当然我们更可以自定义图片来替换默认的大头针,丰富地图内容。

2 开始

首先新建工程,命名为MapKitTutorial,然后添加一个Map Kit View到Storyboard中。先拖拽地图视图到充满屏幕,然后选择添加建议的约束即可,添加完约束效果如图1所示。

然后需要在ViewController.m中添加Map View的outlet关联,通过CTRL+DRAG即可,命名为mapView,代码如下,别忘记引入MapKit头文件,注意要先导入MapKit库(Xcode7.3里面,先选择工程,然后在Capabilities那一项把Maps开关打开):

......
#import <MapKit/MapKit.h>
@interface ViewController ()
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@end

这样,我们编译运行项目,可以看到地图出现了,默认显示的是中国地图在中央位置,这个应该是跟系统环境相关。如图2所示:

3 设置可视区域

接下来重点来了,我们要设置一个可视区域。学过地理
的都知道(我是地理盲),一个地理位置我们是通过纬度和经度来确定一个位置,纬度中北纬和南纬各分为90度,经度西经和东经则各为180度。在iOS开发中,北纬和东经我们用正数表示,南纬和西经用负数表示。

接下来我们要设置一个可视区域,不设置我们看到的只是一个默认区域,如前面看到的一样。设置可视区域的代码如下,然后在方法viewDidLoad中加入调用:

- (void)centerMapOnLocation {//1 设置好纬度和经度CLLocationCoordinate2D initialLocation = {21.282778, -157.829444}; CLLocationDistance regionRadius = 1000;MKCoordinateRegion coordinateRegion = MKCoordinateRegionMakeWithDistance(initialLocation, regionRadius * 2, regionRadius * 2);[self.mapView setRegion:coordinateRegion];
}

这里来解析一下,首先是设置好中心点的经纬度。然后是设置区域半径,包括横向和纵向半径,这里都设置的为2000米(南北和东西的跨度范围)。接着根据中心点经纬度和区域半径创建一个Region,最后调用MapView的setRegion方法即可。这时我们再运行代码可以看到效果如图3所示,我们看到与前面不同了,确实地图已经定位到我们设置的中心点和区域大小了:

4 设置标记

接下来来设置一个标记,也就是通常见到的那种大头针。先新建一个类Artwork来表示标记内容,包括位置坐标,标题和副标题等。位置坐标用于确定大头针位置,而标题和副标题则是点击大头针的时候显示的内容。

@interface Artwork : NSObject <MKAnnotation>@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@property (nonatomic, strong) NSString *locationName;
@property (nonatomic, strong) NSString *discipline;
@property (nonatomic) CLLocationCoordinate2D coordinate;- (instancetype)init:(NSString *)title
locationName:(NSString *)locationNamediscipline:(NSString *)discipline
coordinate:(CLLocationCoordinate2D)coordinate;@end

类Artwork定义如上所示,然后在ViewController.m中加入添加大头针的代码:

- (void)addAnnotation {CLLocationCoordinate2D coordinate = {21.283921, -157.831661};Artwork *artwork = [[Artwork alloc] init: @"King David Kalakaua"locationName: @"Waikiki Gateway Park"discipline: @"Sculpture"coordinate: coordinate];[self.mapView addAnnotation:artwork];
}

注意这里的坐标暂时是自己手动指定,在后面我们会从一个JSON文件中解析一系列的坐标位置然后设置多个大头针。然后里面的locationName其实是位置名字,而MKAnnotation是一个协议,地图标记的协议,它里面主要定义了一系列的属性值(这里可以发现协议不只有方法,也可以定义属性的),就是标记必须的几个属性title,subtitle,coordinate。
然后在viewDidLoad中加入该方法的调用,可以看到大头针显示,点击可以看到title和subtitle的显示。

仅仅这样当然是不够的,为了APP的个性化,我们希望可以自定义大头针显示方式,可以通过设置ViewController实现协议MKMapViewDelegate,然后将mapView的delegate设置为ViewController,并在ViewController中实现协议的viewForAnnotation方法即可。代码如下:

- (void)viewDidLoad {[super viewDidLoad];[self centerMapOnLocation];[self addAnnotation];//1新增delegate设置self.mapView.delegate = self;
}//2 新增代理方法实现
#pragma MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {if ([annotation isKindOfClass:[Artwork class]]) {NSString *identifier = @"pin";MKPinAnnotationView *view = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];if (!view) {view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];//自定义后需要设置canShowCallout为YES,不然点击不会显示信息。view.canShowCallout = YES;//设置信息展示偏移view.calloutOffset = CGPointMake(-10, 5);//设置信息按钮view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];}//设置大头针颜色view.pinTintColor = [UIColor blueColor];      return view;}return nil;
}

方法viewForAnnotation中我们定义了大头针的信息偏移和在显示内容中添加了一个信息按钮。偏移位置是针对大头针的中间顶部而言的,这里我们设置信息展示的X轴向左偏移中间位置10个Point,Y轴则从顶部往下移动5个Point,并将大头针的颜色设置为蓝色,运行效果如图5所示。

5 启动地图APP

上一节点击信息按钮,并没有反应,接下来就要加入点击信息按钮的事件响应,这里我们是跳转到地图app中,显示从当前位置到公园的驾驶路线。

首先需要在类Artwork中加入一个方法,用来创建MapItem。这里需要导入Contacts头文件(原文中用的是Address头文件,iOS9以后的系统中已经不用Address,所以我这里用Contacts来替代)。

#import <Contacts/Contacts.h>
- (MKMapItem *)mapItem {NSDictionary *addressDictionary = @{CNPostalAddressStreetKey: self.locationName};MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:self.coordinate addressDictionary:addressDictionary];MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];return mapItem;
}

然后在ViewController中实现另外一个协议方法如下。另外,在Xcode菜单栏的Product\Scheme\Edit Scheme选择Run的Options选项,设置好默认位置为Honolulu,如图6所示。这样点击右侧的信息按钮,就会跳转到地图APP中了(这里可能是由于高德地图问题,显示不了驾驶路线,暂时没有找到解决方法,若有知道的,麻烦告知一声)。

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {Artwork *artwork = (Artwork *)view.annotation;NSDictionary *launchOptions = @{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving};[[artwork mapItem] openInMapsWithLaunchOptions:launchOptions];
}

运行效果如下:

6 用户位置授权

在iOS应用中,如果应用要请求位置信息,一般是需要提示用户是否授权的,这个功能怎么实现呢?首先在ViewController中加入CLLocationManager,然后在viewDidAppear中加入请求授权的函数调用,如果一次请求授权允许了,系统会记录授权的状态,下次启动应用就不需要再次授权了。如果拒绝授权了,以后要开启只能到系统设置里面开启。

注意:一般请求授权分为两种方式,一种是requestWhenInUseAuthorization表示只有应用在前台允许的时候获取位置信息,而另外一种是requestAlwaysAuthorization表示只要应用在运行就可以获取位置信息,不管在前台还是后台运行,为了不泄露隐私,苹果官方是建议用第一种,即在前台运行的时候运行访问位置信息。

另外一个容易忽视的一点,就是还需要在项目的Info.plist中加入一个配置。配置键名为NSLocationWhenInUseUsageDescription,内容为请求授权的文字信息,本项目填的信息为To show you cool things nearby

@property (strong, nonatomic) CLLocationManager *locationManager;- (void)checkLocationStatus {if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {self.mapView.showsUserLocation = YES;} else {[self.locationManager requestWhenInUseAuthorization];}
}

这样在启动应用的时候,就会弹出一个提示框,内容为应用请求访问您的位置信息,让你决定是否授权。效果如图8所示:

7 其他

原文中还有一节是通过一个JSON文件来设置多个大头针,并根据位置信息不同设置不同的大头针的颜色,与设置一个大头针效果类似,只是多了JSON解析的步骤,这里不再赘述,可以参见我的项目最终代码。

另外,地图里面还可以设置覆盖层(overlay),比如用图片来设置覆盖层,或者设置路径,多边形等,可以源码包看看。

8 项目文件截图


iOS学习笔记-地图MapKit入门

代码地址如下:
http://www.demodashi.com/demo/11682.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

iOS学习笔记-地图MapKit入门相关推荐

  1. iOS学习笔记11-多线程入门

    一.iOS多线程 iOS多线程开发有三种方式: NSThread NSOperation GCD iOS在每个进程启动后都会创建一个主线程,更新UI要在主线程上,所以也称为UI线程,是其他线程的父线程 ...

  2. iOS学习笔记11 多线程入门

    ###一.iOS多线程 ######iOS多线程开发有三种方式: NSThread NSOperation GCD iOS在每个进程启动后都会创建一个主线程,更新UI要在主线程上,所以也称为UI线程, ...

  3. IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应

    (转)IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应 IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油 ...

  4. Hadoop学习笔记(1) ——菜鸟入门

     Hadoop学习笔记(1) --菜鸟入门 Hadoop是什么?先问一下百度吧: [百度百科]一个分布式系统基础架构,由Apache基金会所开发.用户能够在不了解分布式底层细节的情况下.开发分布式 ...

  5. OpenCV for Ios 学习笔记(4)-标记检测1

    本文原始地址:OpenCV for Ios 学习笔记(4)-标记检测1 简单的标记经常是以白色块和黑色块构成的规则图形.因为我们预先知道这些因素,所以我们可以很容易检测标记. 如图: 首先,我们需要找 ...

  6. IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法...

    IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法 Author:hmjiangqq Email:jiangqqlmj@163.com ...

  7. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  8. iOS学习笔记-自己动手写RESideMenu

    代码地址如下: http://www.demodashi.com/demo/11683.html 很多app都实现了类似RESideMenu的效果,RESideMenu是Github上面一个stars ...

  9. iOS学习笔记-自定义过渡动画

    代码地址如下: http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swi ...

最新文章

  1. Java 中如何模拟真正的同时并发请求?
  2. ON DUPLICATE KEY UPDATE 用法与说明
  3. Ubuntu 12.10使用apt安装Oracle/Sun JDK
  4. idea打war包时,JDK版本的问题解决方式
  5. 19 SD配置-主数据-定义通用界限
  6. 一个java 验证码的实现提供多种的实现
  7. 包裹遭联邦快递不正常“转运” 华为:将重新审视双方合作关系
  8. linux中df和ls区别,linux系统文件大小ls、df、du命令的区别
  9. linux systemd命令,systemd命令
  10. 2018 Multi-University Training Contest 3: G. Interstellar Travel(凸包)
  11. Java学习路线图,全套Java基础视频教程
  12. Verilog实现的格雷码与二进制码的互相转换
  13. Chrome 里的小恐龙游戏是怎么做出来的?
  14. Gestalt laws
  15. 穿山甲 groMore 配置广告位 穿山甲/优良汇
  16. 青岛软控为机电软一体化企业的PLM建设树立样板
  17. 怎样批量修改文件名不要括号?
  18. 二、编写输出“Hello World”
  19. java计算机毕业设计宠物医院管理源码+数据库+系统+lw文档+部署
  20. VMWare使用鼠标额外的功能键

热门文章

  1. 在linux下做源码免杀,Cobaltstrike免杀从源码级到落地思维转变
  2. 网段和子网的区别_石笼网袋和石笼网的区别
  3. 【STM32】【STM32CubeMX】STM32CubeMX的使用之四:IIC总线协议驱动SHT30温湿度传感器
  4. Linux内核分析 - 网络[十四]:IP选项
  5. android 画面,Android 界面组成
  6. 解析java程序设计第二版答案,解析Java程序设计答案
  7. linux 将任务挂到后台,linux下使用screen或则nohup将任务放到后台运行
  8. Spring/Spring MVC-面试题
  9. 微信小程序|开发实战篇之四
  10. 基于共享内存、信号、命名管道和Select模型实现聊天窗口