地图显示
MapKit框架的使用
导入主头文件
#import <MapKit/MapKit.h>
MapKit框架使用须知
MapKit框架中所有数据类型的前缀都是MK
MapKit有一个比较重要的UI控件:MKMapView,专门用于地图显示
跟踪显示用户的位置
设置MKMapView的userTrackingMode属性可以跟踪显示用户的当前位置
MKUserTrackingModeNone :不跟踪用户的位置
MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置
MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转
下图是跟踪效果
蓝色发光圆点就是用户的当前位置
蓝色发光圆点和红色圆点,专业术语叫做“大头针”
地图的类型
可以通过设置MKMapView的mapType设置地图类型(mapViewType是枚举类型)
MKMapTypeStandard // 普通地图(左图)
MKMapTypeSatellite // 卫星云图 (中图)
MKMapTypeHybrid // 普通地图覆盖于卫星云图之上(右图)
MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0) // 地形和建筑物的三维模型
MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0) // 显示道路和附加元素的Flyover
MKMapView的代理
MKMapView是专门用来显示地图的视图,可以设置一个代理对象,用来监听地图的相关行为,常见的代理方法有:
1 // 一个位置更改默认只会调用一次,不断监测用户的当前位置时每次都会调用这个方法,把用户的最新位置(userLocation参数)传进来. 2 3 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation; 4 5 // 地图的显示区域即将发生改变的时候调用 6 - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated; 7 8 // 地图的显示区域已经发生改变的时候调用 9 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
MKUserLocation
MKUserLocation其实是个大头针模型,包括以下属性
1 // 显示在大头针上的标题 2 @property (nonatomic, copy) NSString *title; 3 4 // 显示在大头针上的子标题 5 @property (nonatomic, copy) NSString *subtitle; 6 7 // 地理位置信息(大头针钉在什么地方) 8 @property (readonly, nonatomic) CLLocation *location;
设置地图的显示
通过MKMapView的下列方法,可以设置地图显示的位置和区域
1 // 设置地图的中心点位置 2 @property (nonatomic) CLLocationCoordinate2D centerCoordinate; 3 4 -(void)setCenterCoordinate: (CLLocationCoordinate2D)coordinate animated:(BOOL)animated; 5 6 @property (nonatomic) MKCoordinateRegion region; 7 - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
MKCoordinateRegion
MKCoordinateRegion是一个用来表示区域的结构体,定义如下:
1 typedef struct { 2 CLLocationCoordinate2D center; // 区域的中心点位置 3 MKCoordinateSpan span; // 区域的跨度 4 } MKCoordinateRegion;
MKCoordinateSpan的定义
1 typedef struct { 2 CLLocationDegrees latitudeDelta; // 纬度跨度 3 CLLocationDegrees longitudeDelta; // 经度跨度 4 } MKCoordinateSpan;
大头针
地图上的大头针
钉在某个具体位置,用来标识这个位置上有特定的事物(比如这个位置是北京)
大头针模型
在iOS开发中经常会标记某个位置,需要使用地图标注,也就是大家俗称的“大头针”。只要一个NSObject类实现 MKAnnotation协议 就可以作为一个大头针,通常会重写协议中coordinate(标记位置)、title(标题)、subtitle(子标题)三个属性,然后在程序中创建大 头针对象并调用addAnnotation:方法添加大头针即可(之所以iOS没有定义一个基类实现这个协议供开发者使用,多数原因应该是 MKAnnotation是一个模型对象,对于多数应用模型会稍有不同,例如后面的内容中会给大头针模型对象添加其他属性。
1 #import <MapKit/MapKit.h> 2 @interface MyAnnonation : NSObject <MKAnnotation> 3 /** 坐标位置 */ 4 @property (nonatomic, assign) CLLocationCoordinate2D coordinate; 5 /** 标题 */ 6 @property (nonatomic, copy) NSString *title; 7 /** 子标题 */ 8 @property (nonatomic, copy) NSString *subtitle; 9 @end
添加大头针
1 // 初始化大头针对象 2 MyAnnonation *anno = [[MyAnnonation alloc] init]; 3 4 // 设置大头针的标题和子标题以及经纬度 5 anno.title = @"BeiJing"; 6 anno.subtitle = @"welcome"; 7 anno.coordinate = CLLocationCoordinate2DMake(40, 116); 8 [self.mapView addAnnotation:anno];
大头针的基本操作
MKMapView的方法
1 // 添加一个大头针 2 - (void)addAnnotation:(id <MKAnnotation>)annotation; 3 4 // 添加多个大头针 5 - (void)addAnnotations:(NSArray *)annotations; 6 7 // 移除一个大头针 8 - (void)removeAnnotation:(id <MKAnnotation>)annotation; 9 10 // 移除多个大头针 11 - (void)removeAnnotations:(NSArray *)annotation
显示地图完整代码:显示地图、添加大头针
MyAnnotation.h 大头针类
1 #import <Foundation/Foundation.h> 2 #import <MapKit/MapKit.h> 3 @interface MyAnnotation : NSObject<MKAnnotation> 4 // 重写协议中的三个属性coordinate(标记位置)、title(标题)、subtitle(子标题) 5 /// 标记位置 6 @property (nonatomic) CLLocationCoordinate2D coordinate; 7 /// 标题 8 @property (nonatomic, copy) NSString *title; 9 /// 子标题 10 @property (nonatomic, copy) NSString *subtitle; 11 12 @end
ViewController.m
1 #import "ViewController.h" 2 // 引入地图使用的框架MapKit 3 #import <MapKit/MapKit.h> 4 #import <CoreLocation/CoreLocation.h> 5 #import "MyAnnotation.h" 6 7 @interface ViewController ()<MKMapViewDelegate> 8 /// 定位管理器 9 @property (nonatomic, strong)CLLocationManager *locationManager; 10 /// 用来显示地图的视图控件 11 @property (nonatomic, strong)MKMapView *mapView; 12 @end 13 14 @implementation ViewController 15 16 - (void)viewDidLoad { 17 [super viewDidLoad]; 18 // 创建视图 19 [self createMapView]; 20 } 21 22 #pragma mark - 创建视图 23 - (void)createMapView { 24 // 初始化地图视图,并添加到当前视图上 25 self.mapView = [[MKMapView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 [self.view addSubview:self.mapView]; 27 // 设置代理 28 self.mapView.delegate = self; 29 // 初始化定位管理器 30 self.locationManager = [[CLLocationManager alloc] init]; 31 // 判断隐私中的定位服务是否开启并授权,如果用户允许定位才能开启相关功能 32 if (![CLLocationManager locationServicesEnabled]) { 33 NSLog(@"当前设备不可用"); 34 } 35 36 if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) { 37 [self.locationManager requestWhenInUseAuthorization]; 38 } 39 // 设置地图的定位追踪 40 /** 41 MKUserTrackingModeNone 不跟踪用户的当前位置 42 MKUserTrackingModeFollow 跟踪并在地图上显示用户的当前位置 43 MKUserTrackingModeFollowWithHeading 跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转 44 */ 45 self.mapView.userTrackingMode = MKUserTrackingModeFollow; 46 /** 47 MKMapTypeStandard 普通地图 48 MKMapTypeSatellite 卫星云图 49 MKMapTypeHybrid 普通地图覆盖于卫星云图之上 50 MKMapTypeSatelliteFlyover 地形和建筑物的三维模型 51 MKMapTypeHybridFlyover 显示道路和附加元素的Flyover 52 */ 53 self.mapView.mapType = MKMapTypeStandard; 54 55 // 添加大头针 56 [self addAnnotation]; 57 } 58 59 60 #pragma mark - 添加大头针 61 - (void)addAnnotation { 62 // 创建位置 63 CLLocationCoordinate2D location1 = CLLocationCoordinate2DMake(40, 116); 64 CLLocationCoordinate2D location2 = CLLocationCoordinate2DMake(39, 121); 65 CLLocationCoordinate2D location3 = CLLocationCoordinate2DMake(31, 121); 66 // 创建大头针 67 MyAnnotation *annotation1 = [[MyAnnotation alloc] init]; 68 annotation1.coordinate = location1; 69 annotation1.title = @"BeiJing"; 70 annotation1.subtitle = @"welcome"; 71 72 MyAnnotation *annotation2 = [[MyAnnotation alloc] init]; 73 annotation2.coordinate = location2; 74 annotation2.title = @"dalian"; 75 annotation2.subtitle = @"welcome"; 76 77 MyAnnotation *annotation3 = [[MyAnnotation alloc] init]; 78 annotation3.coordinate = location3; 79 annotation3.title = @"shanghai"; 80 annotation3.subtitle = @"welcome"; 81 // 将大头针添加到地图视图上 82 [self.mapView addAnnotations:@[annotation1, annotation2, annotation3]]; 83 } 84 85 86 @end
四、自定义大头针
很多情况下,需要自定义大头针的显示样式,比如显示一张图片
设置MKMapView的代理
实现下面的代理方法,返回大头针控件
1 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
根据传进来的(id <MKAnnotation>)annotation参数创建并返回对应的大头针控件
代理方法的使用注意
1、如果返回nil,显示出来的大头针就采取系统的默认样式
2、标识用户位置的蓝色发光圆点,它也是一个大头针,当显示这个大头针时,也会调用代理方法
3、因此,需要在代理方法中分清楚(id <MKAnnotation>)annotation参数代表自定义的大头针还是蓝色发光圆点
MKAnnotationView
地图上的大头针控件是MKAnnotationView,MKAnnotationView的使用和UITableViewCell一样都是根据重用标识符从重用池中获取的,与UITableViewCell的原理一样。
MKAnnotationView的属性:
1 // 大头针模型 2 @property (nonatomic, strong) id <MKAnnotation> annotation; 3 4 // 显示的图片 5 @property (nonatomic, strong) UIImage *image; 6 7 // 是否显示标注 8 @property (nonatomic) BOOL canShowCallout; 9 10 // 标注的偏移量 11 @property (nonatomic) CGPoint calloutOffset; 12 13 // 标注右边显示什么控件 14 @property (strong, nonatomic) UIView *rightCalloutAccessoryView; 15 16 // 标注左边显示什么控件 17 @property (strong, nonatomic) UIView *leftCalloutAccessoryView;
MKPinAnnotationView
MKPinAnnotationView是MKAnnotationView的子类
MKPinAnnotationView比MKAnnotationView多了2个属性
1 // 大头针颜色 2 @property (nonatomic) MKPinAnnotationColor pinColor; 3 4 // 大头针第一次显示时是否从天而降 5 @property (nonatomic) BOOL animatesDrop;
自定义大头针完整代码:设置图片,设置左视图
MyAnnotation.h 自定义大头针类
1 #import <Foundation/Foundation.h> 2 #import <MapKit/MapKit.h> 3 @interface MyAnnotation : NSObject<MKAnnotation> 4 // 重写协议中的三个属性coordinate(标记位置)、title(标题)、subtitle(子标题) 5 /// 标记位置 6 @property (nonatomic) CLLocationCoordinate2D coordinate; 7 /// 标题 8 @property (nonatomic, copy) NSString *title; 9 /// 子标题 10 @property (nonatomic, copy) NSString *subtitle; 11 // 自定义大头针 12 // 大头针图片 13 @property (nonatomic, strong)UIImage *image; 14 @end
ViewController.m
1 #import "ViewController.h" 2 // 引入地图使用的框架MapKit 3 #import <MapKit/MapKit.h> 4 #import <CoreLocation/CoreLocation.h> 5 #import "MyAnnotation.h" 6 7 @interface ViewController ()<MKMapViewDelegate> 8 /// 定位管理器 9 @property (nonatomic, strong)CLLocationManager *locationManager; 10 /// 用来显示地图的视图控件 11 @property (nonatomic, strong)MKMapView *mapView; 12 @end 13 14 @implementation ViewController 15 16 - (void)viewDidLoad { 17 [super viewDidLoad]; 18 // 创建视图 19 [self createMapView]; 20 } 21 22 #pragma mark - 创建视图 23 - (void)createMapView { 24 // 初始化地图视图,并添加到当前视图上 25 self.mapView = [[MKMapView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 [self.view addSubview:self.mapView]; 27 // 设置代理 28 self.mapView.delegate = self; 29 // 初始化定位管理器 30 self.locationManager = [[CLLocationManager alloc] init]; 31 // 判断隐私中的定位服务是否开启并授权,如果用户允许定位才能开启相关功能 32 if (![CLLocationManager locationServicesEnabled]) { 33 NSLog(@"当前设备不可用"); 34 } 35 36 if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) { 37 [self.locationManager requestWhenInUseAuthorization]; 38 } 39 // 设置地图的定位追踪 40 /** 41 MKUserTrackingModeNone 不跟踪用户的当前位置 42 MKUserTrackingModeFollow 跟踪并在地图上显示用户的当前位置 43 MKUserTrackingModeFollowWithHeading 跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转 44 */ 45 self.mapView.userTrackingMode = MKUserTrackingModeFollow; 46 /** 47 MKMapTypeStandard 普通地图 48 MKMapTypeSatellite 卫星云图 49 MKMapTypeHybrid 普通地图覆盖于卫星云图之上 50 MKMapTypeSatelliteFlyover 地形和建筑物的三维模型 51 MKMapTypeHybridFlyover 显示道路和附加元素的Flyover 52 */ 53 self.mapView.mapType = MKMapTypeStandard; 54 55 // 添加大头针 56 [self addAnnotation]; 57 } 58 59 60 #pragma mark - 添加大头针 61 - (void)addAnnotation { 62 // 创建位置 63 CLLocationCoordinate2D location1 = CLLocationCoordinate2DMake(40, 116); 64 CLLocationCoordinate2D location2 = CLLocationCoordinate2DMake(39, 121); 65 CLLocationCoordinate2D location3 = CLLocationCoordinate2DMake(31, 121); 66 // 创建大头针 67 MyAnnotation *annotation1 = [[MyAnnotation alloc] init]; 68 annotation1.coordinate = location1; 69 annotation1.title = @"BeiJing"; 70 annotation1.subtitle = @"welcome"; 71 // ******************************* 72 // 设置图片 73 annotation1.image = [UIImage imageNamed:@"test"]; 74 75 76 MyAnnotation *annotation2 = [[MyAnnotation alloc] init]; 77 annotation2.coordinate = location2; 78 annotation2.title = @"dalian"; 79 annotation2.subtitle = @"welcome"; 80 // ******************************* 81 // 设置图片 82 annotation2.image = [UIImage imageNamed:@"test"]; 83 84 MyAnnotation *annotation3 = [[MyAnnotation alloc] init]; 85 annotation3.coordinate = location3; 86 annotation3.title = @"shanghai"; 87 annotation3.subtitle = @"welcome"; 88 // ******************************* 89 // 设置图片 90 annotation3.image = [UIImage imageNamed:@"test"]; 91 92 93 // 将大头针添加到地图视图上 94 [self.mapView addAnnotations:@[annotation1, annotation2, annotation3]]; 95 } 96 97 98 #pragma mark - ****************************************** 99 #pragma mark - 实现自定义大头针视图的代理方法 100 // 显示大头针时才会调用的方法 101 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { 102 // 判断是否是当前自定义的大头针类 103 if ([annotation isKindOfClass:[MyAnnotation class]]) { 104 // 先定义重用标识 105 static NSString *identifier = @"AnnotationOne"; 106 // 从mapView的重用池中取 107 MKAnnotationView *annotationView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; 108 if (annotationView == nil) { 109 annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; 110 // 允许用户交互 111 annotationView.canShowCallout = YES; 112 // 设置偏移量 (显示标题和子标题的文字与大头针的偏移量) 113 annotationView.calloutOffset = CGPointMake(0, 1); 114 // 设置详情的标题和子标题的左视图 115 annotationView.leftCalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1"]]; 116 } 117 // 修改大头针视图 118 annotationView.annotation = annotation; 119 annotationView.image = ((MyAnnotation *)annotation).image; 120 return annotationView; 121 } else { 122 return nil; 123 } 124 } 125 126 @end
运行效果:
系统自带地图功能使用起来是非常方便的,不需要导入第三方类库等
实际项目开发可根据具体情况、需求来确定是否使用系统自带地图
可以研究一下百度地图,高德地图等功能比较全面的地图
总结:
CLLocationManager 定位的基础信息
CLLocation 位置的地理信息
CLLocationCoordinate2D 存放经纬度的结构体
CLGeocoder地理位置编码与反编码的类
CLPlacemark 地标.
MKMapView 基础地图
MKUserLocation 大头针模型
MKCoordinateRegion 显示区域的结构体
MKAnnotationView 自定义大头针控件