地图显示

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 自定义大头针控件

 

posted @ 2017-02-21 22:44  Leo-Wmw  阅读(211)  评论(0编辑  收藏  举报