iOS原生地图开发详解
在上一篇博客中:http://my.oschina.net/u/2340880/blog/414760。对iOS中的定位服务进行了详细的介绍与参数说明,在开发中,地位服务往往与地图框架结合使用,这篇博客主要对iOS官方的地图框架MapKit.framework进行介绍。
一、初始化地图视图与相关属性方法介绍
1、初始化地图视图
地图视图的展示依赖于MKMapView这个类,这个类继承于UIView,因此和其他View的使用方法类似。在我们需要展现地图的地方:
- (void)viewDidLoad { [super viewDidLoad]; MKMapView * mapView =[[MKMapView alloc]initWithFrame:self.view.frame]; [self.view addSubview:mapView];}
运行发现,一张世界地图就在我们的设备上了,apple内置的地图数据是由高德提供的。
2、系统提供的三种地图样式
可以通过MKMapView的mapType这个属性设置地图的模式:
@property (nonatomic) MKMapType mapType;
枚举如下:
typedef NS_ENUM(NSUInteger, MKMapType) { MKMapTypeStandard = 0,//标准式的行政地图(会显示城市,街道等) MKMapTypeSatellite,//标准的卫星地图 MKMapTypeHybrid//混合地图(在卫星图上显示街道等名称)};
3、设置地图的中心和比例尺
在百度地图等第三方地图服务的SDK中,都会提供一个类似zoomLevel比例尺的属性。通过官方的API设置这个属性有些麻烦,但是也更加灵活。首先,设置地图的中心位置和比例尺是通过region这个属性实现的。region结构体如下:
typedef struct { CLLocationCoordinate2D center;//地图中心的经纬度 MKCoordinateSpan span;//地图显示的经纬度范围} MKCoordinateRegion;
这个结构体中包含了两个结构体,其中CLLocationCoordinate2D很好理解,就是简单的经纬度,解释如下:
typedef struct { CLLocationDegrees latitude;//纬度,北纬为正,南纬为负 CLLocationDegrees longitude;//经度,东经为正,西经为负} CLLocationCoordinate2D;
MKCoordinateSpan这个结构体比较复杂,如下:
typedef struct { CLLocationDegrees latitudeDelta;//纬度范围 CLLocationDegrees longitudeDelta;//经度范围} MKCoordinateSpan;
这个结构体定义的应该是一个范围,因为北纬南纬加起来180°,所以纬度范围的取值应为0-180。同理,经度范围的取值范围为0-360。
通过上面的介绍,我们举个例子,将北京市设为地图的中心区域,并且比例设置为显示北京大小。通过百度,首先知道北京市界的地理坐标为:北纬39”26’至41”03’,东经115”25’至 117”30’。北京市区坐标为:北纬39.9”,东经116. 3”。代码如下:
mapView.region=MKCoordinateRegionMake(CLLocationCoordinate2DMake(39.26, 116.3), MKCoordinateSpanMake(1.8, 2.05));
运行后可以看到,北京市基本上是在地图中心的,效果如下:

注意:MKCoordinateSpan的显示范围是取决于大的一边的,比如如果我们这样写:
MKCoordinateSpanMake(1.8, 360);
最后依然会显示整个世界地图。
- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
这个方法可以在设置后给地图加上动画效果
@property (nonatomic) CLLocationCoordinate2D centerCoordinate;
设置地图的中心点位置
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
设置地图的中心点位置,并附带动画效果
4、坐标转换方法
- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view;
将经纬度转换为视图上的坐标
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view;
将视图上的坐标转换为经纬度
- (CGRect)convertRegion:(MKCoordinateRegion)region toRectToView:(UIView *)view;
将地理显示的区域转换为视图上的坐标区域
- (MKCoordinateRegion)convertRect:(CGRect)rect toRegionFromView:(UIView *)view;
将视图上的坐标区域转换为地理区域
5、MKMapView常用方法和属性
@property (nonatomic, getter=isZoomEnabled) BOOL zoomEnabled;
设置是否允许捏合手势进行地图缩放
@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;
设置是否允许滑动
@property (nonatomic, getter=isRotateEnabled) BOOL rotateEnabled;
设置是否允许旋转地图
@property (nonatomic, getter=isPitchEnabled) BOOL pitchEnabled;
设置是否支持3D效果
@property (nonatomic) BOOL showsPointsOfInterest;
设置是否显示兴趣点,例如学校,医院等
@property (nonatomic) BOOL showsBuildings;
设置是否显示建筑物轮廓,只在标准的地图中有效
@property (nonatomic) BOOL showsUserLocation;
是否显示用户位置
@property (nonatomic) MKUserTrackingMode userTrackingMode;
- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
设置更新用户位置的模式,当显示用户位置设置为YES,这个方法也设置了后,地图框架为我们直接集成了定位,地图上就会显示我们的位置,模式的枚举如下:
typedef NS_ENUM(NSInteger, MKUserTrackingMode) { MKUserTrackingModeNone = 0, // 不跟踪用户位置 MKUserTrackingModeFollow, // 跟踪用户位置 MKUserTrackingModeFollowWithHeading, // 当方向改变时跟踪用户位置}
@property (nonatomic, readonly) MKUserLocation *userLocation;
获取用户位置的标注
@property (nonatomic, readonly, getter=isUserLocationVisible) BOOL userLocationVisible;
获取用户位置是否可见
- (void)addAnnotation:(id <MKAnnotation>)annotation;
在地图上添加一个标注
- (void)addAnnotations:(NSArray *)annotations;
在地图上添加一组标注
- (void)removeAnnotation:(id <MKAnnotation>)annotation;
移除一个标注
- (void)removeAnnotations:(NSArray *)annotations;
移除一组标注
@property (nonatomic, readonly) NSArray *annotations;
获取所有标注数组
- (MKAnnotationView *)viewForAnnotation:(id <MKAnnotation>)annotation;
获取标注的视图
- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier;
获取复用的标注
- (void)selectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;
选中一个标注
- (void)deselectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;
取消选中一个标注
@property (nonatomic, copy) NSArray *selectedAnnotations;
选中标注的数组
- (void)addOverlay:(id <MKOverlay>)overlay level:(MKOverlayLevel)level;
添加一个地图覆盖物,level是设置一个层级,枚举如下:
typedef NS_ENUM(NSInteger, MKOverlayLevel) { MKOverlayLevelAboveRoads = 0, // 覆盖物位于道路之上 MKOverlayLevelAboveLabels//覆盖物位于标签之上}
- (void)addOverlays:(NSArray *)overlays level:(MKOverlayLevel)level;
添加一组地图覆盖物
- (void)removeOverlay:(id <MKOverlay>)overlay;
移除一个地图覆盖物
- (void)removeOverlays:(NSArray *)overlays;
移除一组地图覆盖物
- (void)insertOverlay:(id <MKOverlay>)overlay atIndex:(NSUInteger)index level:(MKOverlayLevel)level;
在索引处插入一个地图覆盖物
- (void)insertOverlay:(id <MKOverlay>)overlay aboveOverlay:(id <MKOverlay>)sibling;
将一个地图覆盖物插在到某个覆盖物之上
- (void)insertOverlay:(id <MKOverlay>)overlay belowOverlay:(id <MKOverlay>)sibling;
将一个地图覆盖物插入到某个覆盖物之下
- (void)exchangeOverlay:(id <MKOverlay>)overlay1 withOverlay:(id <MKOverlay>)overlay2;
替换一个地图覆盖物
@property (nonatomic, readonly) NSArray *overlays;
地图覆盖物数组
- (NSArray *)overlaysInLevel:(MKOverlayLevel)level;
层级属性下的东土覆盖物数组
二、MKMapViewDelegate相关方法解读
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;
地图显示位置将要改变时调用的方法
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
地图显示位置已经改变时调用的方法
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView;
地图将要加载时调用的方法
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView;
地图加载完成时执行的方法
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error;
地图加载失败时执行的方法
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
渲染标注视图时调用的方法,可以通过这个方法自定义标注视图
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
标注添加完成后调用的方法
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view;
选中标注时调用的方法
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view;
取消选中标注时调用的方法
- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView;
将要开始定位用户位置时调用的方法
- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView;
停止定位用户位置时调用的方法
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;
更新用户位置时调用的方法
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error;
更新用户位置失败时调用的方法
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState;
标注拖动状态改变调用的方法,MKAnnotationViewDragState的枚举如下:
typedef NS_ENUM(NSUInteger, MKAnnotationViewDragState) { MKAnnotationViewDragStateNone = 0, // 初始状态 MKAnnotationViewDragStateStarting, // 开始拖动时 MKAnnotationViewDragStateDragging, // 正在拖动 MKAnnotationViewDragStateCanceling, // 取消拖动 MKAnnotationViewDragStateEnding // 结束拖动};
- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
定位用户位置模式改变时调用的方法
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay;
渲染覆盖物视图时调用的方法,可以自定义覆盖物视图
- (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews;
添加完成覆盖物数组执行的方法
原文链接:iOS原生地图开发详解
iOS原生地图开发详解的更多相关文章
- iOS原生地图开发进阶——使用导航和附近兴趣点检索
iOS原生地图开发进阶——使用导航和附近兴趣点检索 iOS中的mapKit框架对国际化的支持非常出色.在前些篇博客中,对这个地图框架的基础用法和标注与覆盖物的添加进行了详细的介绍,这篇博客将介绍两个更 ...
- iOS原生地图开发指南续——大头针与自定义标注
iOS原生地图开发指南续——大头针与自定义标注 出自:http://www.sxt.cn/info-6042-u-7372.html 在上一篇博客中http://my.oschina.net/u/23 ...
- iOS 原生地图 开发
iOS开发有时候用到地图,不少人第一想到的是用第三方.当然有时候为了和安卓同步,可能会一起使用某一第三方.但有时候,我们是可以用原生地图开发的.上面两个示意图是原生地图的自定义开发.运行demo,将展 ...
- iOS 百度地图使用详解
最近仿照美团做了款应用,刚好用到百度地图,高德地图之前用的比较多,只是这个项目的后台服务器是另外一个公司做的,他们用的就是百度地图,现在网上用百度地图的还不算太多,博文也是断断续续的,主要是中间跳跃有 ...
- iOS索引列开发详解
做苹果开发的朋友在地区列表可能会遇到在页面的右侧有一列类似与导航的索引列,这次有机会遇到了,细细研究了一下,原来没有想象中的困难,只需要简单的几步就能做出自己的索引列.本来想和搜索条在一块讲解,后来考 ...
- iOS应用开发详解
<iOS应用开发详解> 基本信息 作者: 郭宏志 出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...
- [转载]Apple Watch 开发详解
Apple Watch 开发详解 Apple Watch现在对于第三方开发者来说更多的还是一块额外的屏幕.暂时WatchKit没有能给出足够的接口.现在Watch App的主要运算逻辑需要依赖iPho ...
- Apple Watch 开发详解
Apple Watch 开发详解 Apple Watch现在对于第三方开发者来说更多的还是一块额外的屏幕.暂时WatchKit没有能给出足够的接口.现在Watch App的主要运算逻辑需要依赖iPho ...
- javacv开发详解之1:调用本机摄像头视频(建议使用javaCV最新版本)
javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...
随机推荐
- Mvc项目架构分享之项目扩展
Mvc项目架构分享之项目扩展 Contents 系列一[架构概览] 0.项目简介 1.项目解决方案分层方案 2.所用到的技术 3.项目引用关系 系列二[架构搭建初步] 4.项目架构各部分解析 5.项目 ...
- 讲解Canvas中的一些重要方法
Canvas所提供的各种方法根据功能来看大致可以分为几类: 第一是以drawXXX为主的绘制方法: 第二是以clipXXX为主的裁剪方法: 第三是以scale.skew.translate和rotat ...
- Android子线程更新UI主线程方法之Handler
背景: 我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的. ...
- Android 计算布局背景的透明度
1.#ff000000 此为16进制颜色代码,前2位ff为透明度,后6位为颜色值(000000为黑色,ffffff为白色,可以用ps等软件获取). 2.透明度分为256阶(0-255),计算机上用16 ...
- [stl] SGI STL的空间配置器
第一级空间配置器 第一级配置以malloc(), free(), realloc()等c函数执行实际的内存配置,释放.重配置操作,并实现出类似c++ new handler的机制.它不能直接使用c++ ...
- Android PopupWindow使用之地区、学校选择二级联动
最近在做一个社交类APP时,希望用户在注册时根据地区来选择自己所在的学校,由于用户手动输入学校,可能会出现各种问题,不利于后面对用户信息的统计.于是决定在客户端做好设置,用户只要根据地区来选择就好.第 ...
- 深入理解Activity -动手写实例来感受Activity的启动模式
介绍 上篇提到了Activity的任务,任务栈,以及启动模式.对这些概念有了了解以后,自己写一下例子来感受一下,就当作复习和加深印象了.如果对概念不熟悉的可以参考:深入理解Activity-任务,回退 ...
- js 毫秒 转 时间 日期 yyyy-mm-dd hh-mm-ss
//格式化时间 var format = function(time, format){ var t = new Date(time); var tf = function(i){return (i ...
- android中的事件传递和处理机制
一直以来,都被android中的事件传递和处理机制深深的困扰!今天特意来好好的探讨一下.现在的感觉是,只要你理解到位,其实事件的 传递和处理机制并没有想象中的那么难.总之,不要自己打击自己,要相信自己 ...
- 在Web api2 中传递复杂参数的一点心得
这两天在做的一个项目基于webapi2,期间遇到了复杂参数传递的问题.其中刚好看到园友的这篇文章,但是我测试收结果是失败的,还不知道是什么原因.最终经过思考后,找到了一种方法,和大家分享下. 在前端我 ...