前言
学习地图,我们必须要接触两个框架:
Core Location,主要包含定位、地理编码、反编码功能,如需了解请移步iOS开发之地图-定位/编码与反编码
MapKit,利用他可以对地图进行精准的控制,比如,放置大头针、地图类型切换,导航等等。
本文我们主要介绍的是使用MapKit框架对地图试图进行精准的控制。
MKMapView
MKMapView是地图展示控件。
MKMapView的常用属性
//跟踪类型,是一个枚举:MKUserTrackingModeNone :不进行用户位置跟踪;MKUserTrackingModeFollow :跟踪用户位置;MKUserTrackingModeFollowWithHeading :跟踪用户位置并且跟踪用户前进方向;
userTrackingMode
//地图类型,是一个枚举:MKMapTypeStandard :标准地图,一般情况下使用此地图即可满足;MKMapTypeSatellite :卫星地图;MKMapTypeHybrid :混合地图,加载最慢比较消耗资源;
mapType
//用户位置,只读属性
userLocation
//当前地图中的所有大头针,只读属性
annotations
// 是否可以缩放
zoomEnabled = NO;
// 是否可以滚动
scrollEnabled = NO;
// 是否可以旋转
rotateEnabled = NO;
// 是否显示3D
pitchEnabled = NO;
// 是否显示指南针
showsCompass = YES;
// 是否显示比例尺
showsScale = YES;
// 是否显示交通
showsTraffic = YES;
// 是否显示建筑物
showsBuildings = YES;
MKMapView的常用方法
******对象方法*****
//添加大头针,对应的有添加大头针数组
- (void)addAnnotation:(id)annotation;
//删除大头针,对应的有删除大头针数组
- (void)removeAnnotation:(id)annotation;
//设置地图显示区域,用于控制当前屏幕显示地图范围
- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
//设置地图中心点位置
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
//将地理坐标(经纬度)转化为数学坐标(UIKit坐标)
- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView*)view;
//将数学坐标转换为地理坐标
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView*)view;
//从缓存池中取出大头针,类似于UITableView中取出UITableViewCell,为了进行性能优化而设计
- (MKAnnotationView*)dequeueReusableAnnotationViewWithIdentifier:(NSString*)identifier;
//选中指定的大头针
- (void)selectAnnotation:(id)annotation animated:(BOOL)animated;
//取消选中指定的大头针
- (void)deselectAnnotation:(id)annotation animated:(BOOL)animated;
******代理方法*****
//用户位置发生改变时触发(第一次定位到用户位置也会触发该方法)
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ;
//显示区域发生改变后触发
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ;
//地图加载完成后触发
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView;
//显示大头针时触发,返回大头针视图,通常自定义大头针可以通过此方法进行
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation;
//点击选中某个大头针时触发
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
//取消选中大头针时触发
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
//渲染地图覆盖物时触发
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay
MKMapView显示当前位置的步骤
1.导入MapKit框架
#import
2.使用定位管理器CLLocationManager做定位授权
_locationManager = [[CLLocationManager alloc]init];
[_locationManager requestAlwaysAuthorization];//始终授权
[_locationManager requestWhenInUseAuthorization];// 使用时授权
3.创建MKMapView地图试图,并添加到他的父试图上面,我的_mapView已设为全局变量
_mapView = [[MKMapView alloc]initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
4.设置相应属性
//跟踪类型,是一个枚举:MKUserTrackingModeNone :不进行用户位置跟踪;MKUserTrackingModeFollow :跟踪用户位置;MKUserTrackingModeFollowWithHeading :跟踪用户位置并且跟踪用户前进方向;userTrackingMode
_mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
//地图类型,是一个枚举:MKMapTypeStandard :标准地图,一般情况下使用此地图即可满足;MKMapTypeSatellite :卫星地图;MKMapTypeHybrid :混合地图,加载最慢比较消耗资源;mapType
_mapView.mapType = MKMapTypeStandard;
// 显示标尺
_mapView.showsScale = YES;
// 显示交通状态
_mapView.showsTraffic = YES;
// 显示罗盘
_mapView.showsCompass = YES;
5.挂上代理
_mapView.delegate = self;
6.显示用户位置
_mapView.showsUserLocation = YES;
7.实现代理方法,不止有这些还有很多其他的代理方法。
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
//让用户定位到当前位置
_mapView.centerCoordinate = userLocation.coordinate;
[_mapView setRegion:MKCoordinateRegionMake(userLocation.coordinate, MKCoordinateSpanMake(0.1, 0.1))];
/*
* 设置地图上所显示的区域
* CLLocationCoordinate2D 设置该区域的中心点
* MKCoordinateSpan 设置该区域的经纬度跨度
* 例如:中国经纬度
经度范围:73.33E 至 135.05E
纬度范围:2.51N 至 53.33N
为了简便,我们去掉小数
中国中心点的纬度是(3 + 53)/ 2 = 北纬28度
中国中心点的经度是(73 + 135)/ 2 = 东经104度
中国纬度跨度是53 - 3 = 50度
中国经度跨度是135 - 73 = 62度
*/
// MKCoordinateSpan span = MKCoordinateSpanMake(50, 62);//跨度越大,地图所显示的区域越大
// CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(28, 104);
// MKCoordinateRegion regoin = MKCoordinateRegionMake(coordinate, span);
// [_mapView setRegion:regoin animated:YES];
}
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error{
NSLog(@"定位失败%@",error);
}
总结,如果无法显示自己的位置,检查以下几点:
是否将定位管理器设为全局变量
是否在项目中进行定位授权,是否在Info.plist中配置
是否将showsUserLocation设为YES。
是否配置模拟器 点击模拟器 -> 菜单栏Dubug -> Location -> Apple来使模拟器定位,然后使用Custom Location配置模拟器的经纬度。
最终效果如下:
自定义用户位置的大头针
其实上图中间的那个点就是一个大头针。现在我们要做的就是自定义这个大头针的样式,写代码之前需先了解以下知识:
MKAnnotationView:大头针试图,能够自定义,用户当前位置的大头针默认样式是一个原点,非用户当前位置的大头针,系统默认用一个类似图钉样式的试图显示。
MKAnnotation:大头针的数据模型,只要一个NSObject类实现MKAnnotation协议就可以作为一个大头针数据模型,通常会重写协议中coordinate(标记位置)、title(标题)、subtitle(子标题)三个属性来自定义大头针的数据模型。
给地图试图添加大头针的原理如下
准备大头针数据模型
使用地图试图调用addAnnotaion给地图试图添加大头针数据模型
然后MKMapView会将数据模型传给一个代理方法,该代理方法会将该大头针数据模型包装到一个大头针试图(在该代理方法内可以自定义大头针试图),然后返回该大头针试图,返回的带有数据模型的大头针试图便会显示在地图上,如果返回为nil,则系统会默认一个大头针试图显示在地图上面。