一、MapKit框架的使用
typedef struct {
CLLocationCoordinate2D center; // 区域的中心点位置
MKCoordinateSpan span; // 区域的跨度
} MKCoordinateRegion;
typedef struct {
CLLocationDegrees latitudeDelta; // 纬度跨度
CLLocationDegrees longitudeDelta; // 经度跨度
} MKCoordinateSpan;
七、大头针
1.大头针的基本操作
2.大头针模型
#import <MapKit/MapKit.h>
@interface MJTuangouAnnotation : NSObject <MKAnnotation>
/** 坐标位置 */
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
/** 标题 */
@property (nonatomic, copy) NSString *title;
/** 子标题 */
@property (nonatomic, copy) NSString *subtitle;
@end
MJTuangouAnnotation *anno = [[MJTuangouAnnotation alloc] init];
anno.title = @"传智播客iOS学院";
anno.subtitle = @"全部课程15折,会员20折,老学员30折";
anno.coordinate = CLLocationCoordinate2DMake(40, 116);
[self.mapView addAnnotation:anno];
八、自定义大头针
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// 判断annotation的类型
if (![annotation isKindOfClass:[MJTuangouAnnotation class]]) return nil;
// 创建MKAnnotationView
static NSString *ID = @"tuangou";
MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
if (annoView == nil) {
annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
annoView.canShowCallout = YES;
}
// 传递模型数据
annoView.annotation = annotation;
// 设置图片
MJTuangouAnnotation *tuangouAnnotation = annotation;
annoView.image = [UIImage imageNamed:tuangouAnnotation.icon];
return annoView;
}
九、MKAnnotationView
代码
1 // 2 // ViewController.m 3 // IOS_0403_MapKit基本使用 4 // 5 // Created by ma c on 16/4/3. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import <MapKit/MapKit.h> 11 12 @interface ViewController ()<MKMapViewDelegate> 13 14 @property (weak, nonatomic) IBOutlet MKMapView *customMapView; 15 @property (nonatomic, strong) CLLocationManager *mgr; 16 @property (nonatomic, strong) CLGeocoder *geocoder; 17 18 @end 19 20 @implementation ViewController 21 22 /* 23 NSLocationWhenInUseDescription,允许在前台获取GPS的描述 24 NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述 25 26 */ 27 28 - (void)viewDidLoad { 29 [super viewDidLoad]; 30 [self test]; 31 } 32 33 - (void)test 34 { 35 if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { 36 //请求权限 37 self.mgr = [[CLLocationManager alloc] init]; 38 [self.mgr requestAlwaysAuthorization]; 39 } 40 self.customMapView.delegate = self; 41 42 //设置地图类型 43 self.customMapView.mapType = MKMapTypeStandard; 44 //设置不允许旋转 45 self.customMapView.rotateEnabled = NO; 46 //追踪我的位置 47 self.customMapView.userTrackingMode = MKUserTrackingModeFollow; 48 } 49 #pragma mark - MKMapViewDelegate 50 51 //每次更新用户的位置就会调用 52 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 53 { 54 55 //反向地理编码 56 [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { 57 CLPlacemark *placeMark = [placemarks firstObject]; 58 //设置大头针显示内容 59 userLocation.title = placeMark.name; 60 userLocation.subtitle = placeMark.locality; 61 }]; 62 63 //移动地图到当前用户所在的位置 64 [self.customMapView setCenterCoordinate:userLocation.location.coordinate animated:YES]; 65 66 //设置地图显示的区域 67 //获取用户位置 68 CLLocationCoordinate2D center = userLocation.location.coordinate; 69 //设置经纬度跨度 70 MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1); 71 MKCoordinateRegion region = MKCoordinateRegionMake(center, span); 72 [self.customMapView setRegion:region animated:YES]; 73 74 } 75 //地图区域将要改变时调用 76 - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated 77 { 78 NSLog(@"regionWillChangeAnimated"); 79 } 80 81 //地图区域改变完成时调用 82 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 83 { 84 NSLog(@"regionDidChangeAnimated"); 85 86 NSLog(@"%f %f", self.customMapView.region.span.latitudeDelta, self.customMapView.region.span.longitudeDelta); 87 } 88 89 90 #pragma mark - 懒加载 91 - (CLGeocoder *)geocoder 92 { 93 if(!_geocoder){ 94 _geocoder = [[CLGeocoder alloc] init]; 95 96 } 97 return _geocoder; 98 } 99 100 101 @end
自定义大头针
1 // 2 // ViewController.m 3 // IOS_0403_MapKit基本使用 4 // 5 // Created by ma c on 16/4/3. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import <MapKit/MapKit.h> 11 12 @interface ViewController ()<MKMapViewDelegate> 13 14 @property (weak, nonatomic) IBOutlet MKMapView *customMapView; 15 @property (nonatomic, strong) CLLocationManager *mgr; 16 @property (nonatomic, strong) CLGeocoder *geocoder; 17 18 @end 19 20 @implementation ViewController 21 22 /* 23 NSLocationWhenInUseDescription,允许在前台获取GPS的描述 24 NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述 25 26 */ 27 28 - (void)viewDidLoad { 29 [super viewDidLoad]; 30 [self test]; 31 } 32 33 - (void)test 34 { 35 if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { 36 //请求权限 37 self.mgr = [[CLLocationManager alloc] init]; 38 [self.mgr requestAlwaysAuthorization]; 39 } 40 self.customMapView.delegate = self; 41 42 //设置地图类型 43 self.customMapView.mapType = MKMapTypeStandard; 44 //设置不允许旋转 45 self.customMapView.rotateEnabled = NO; 46 //追踪我的位置 47 self.customMapView.userTrackingMode = MKUserTrackingModeFollow; 48 } 49 #pragma mark - MKMapViewDelegate 50 51 //每次更新用户的位置就会调用 52 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 53 { 54 55 //反向地理编码 56 [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { 57 CLPlacemark *placeMark = [placemarks firstObject]; 58 //设置大头针显示内容 59 userLocation.title = placeMark.name; 60 userLocation.subtitle = placeMark.locality; 61 }]; 62 63 //移动地图到当前用户所在的位置 64 [self.customMapView setCenterCoordinate:userLocation.location.coordinate animated:YES]; 65 66 //设置地图显示的区域 67 //获取用户位置 68 CLLocationCoordinate2D center = userLocation.location.coordinate; 69 //设置经纬度跨度 70 MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1); 71 MKCoordinateRegion region = MKCoordinateRegionMake(center, span); 72 [self.customMapView setRegion:region animated:YES]; 73 74 } 75 //地图区域将要改变时调用 76 - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated 77 { 78 NSLog(@"regionWillChangeAnimated"); 79 } 80 81 //地图区域改变完成时调用 82 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 83 { 84 NSLog(@"regionDidChangeAnimated"); 85 86 NSLog(@"%f %f", self.customMapView.region.span.latitudeDelta, self.customMapView.region.span.longitudeDelta); 87 } 88 89 90 #pragma mark - 懒加载 91 - (CLGeocoder *)geocoder 92 { 93 if(!_geocoder){ 94 _geocoder = [[CLGeocoder alloc] init]; 95 96 } 97 return _geocoder; 98 } 99 100 101 @end 102 103 104 // 105 // Annotation.m 106 // IOS_0403_自定义大头针 107 // 108 // Created by ma c on 16/4/3. 109 // Copyright © 2016年 博文科技. All rights reserved. 110 // 111 112 #import "Annotation.h" 113 114 @implementation Annotation 115 116 @end
1 // 2 // BZAnnotationView.h 3 // IOS_0403_自定义大头针 4 // 5 // Created by ma c on 16/4/3. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import <MapKit/MapKit.h> 10 11 @interface BZAnnotationView : MKAnnotationView 12 /** 13 * 快速创建方法 14 * 15 * @param mapView 地图 16 * 17 * @return 大头针 18 */ 19 + (instancetype)annotationViewWithMap:(MKMapView *)mapView; 20 21 @end 22 23 24 // 25 // BZAnnotationView.m 26 // IOS_0403_自定义大头针 27 // 28 // Created by ma c on 16/4/3. 29 // Copyright © 2016年 博文科技. All rights reserved. 30 // 31 32 #import "BZAnnotationView.h" 33 #import "Annotation.h" 34 35 @implementation BZAnnotationView 36 37 - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier 38 { 39 if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) { 40 // 初始化 41 // 设置大头针标题是否显示 42 self.canShowCallout = YES; 43 44 // 设置大头针左边的辅助视图 45 self.leftCalloutAccessoryView = [[UISwitch alloc] init]; 46 47 // 设置大头针右边的辅助视图 48 self.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd]; 49 } 50 return self; 51 } 52 53 + (instancetype)annotationViewWithMap:(MKMapView *)mapView 54 { 55 static NSString *identifier = @"anno"; 56 57 // 1.从缓存池中取 58 BZAnnotationView *annoView = (BZAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; 59 // 2.如果缓存池中没有, 创建一个新的 60 if (annoView == nil) { 61 annoView = [[BZAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier]; 62 } 63 return annoView; 64 } 65 66 //- (void)setAnnotation:(id<MKAnnotation>)annotation 67 - (void)setAnnotation:(Annotation *)annotation 68 { 69 [super setAnnotation:annotation]; 70 71 //处理自己特有的操作 72 self.image = [UIImage imageNamed:annotation.icon]; 73 74 } 75 76 77 @end
1 // 2 // ViewController.m 3 // IOS_0403_自定义大头针 4 // 5 // Created by ma c on 16/4/3. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import <MapKit/MapKit.h> 11 #import "Annotation.h" 12 #import "BZAnnotationView.h" 13 14 @interface ViewController ()<MKMapViewDelegate> 15 16 @property (weak, nonatomic) IBOutlet MKMapView *customMapView; 17 @property (nonatomic, strong) CLGeocoder *geocoder; 18 @property (nonatomic, strong) CLLocationManager *mgr; 19 - (IBAction)addAnno; 20 21 @end 22 23 @implementation ViewController 24 25 - (void)viewDidLoad { 26 [super viewDidLoad]; 27 28 [self test]; 29 } 30 31 - (void)test 32 { 33 if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { 34 //请求权限 35 self.mgr = [[CLLocationManager alloc] init]; 36 [self.mgr requestAlwaysAuthorization]; 37 } 38 self.customMapView.delegate = self; 39 40 //设置地图类型 41 self.customMapView.mapType = MKMapTypeStandard; 42 //设置不允许旋转 43 self.customMapView.rotateEnabled = NO; 44 //追踪我的位置 45 self.customMapView.userTrackingMode = MKUserTrackingModeFollow; 46 } 47 48 //添加大头针 49 - (IBAction)addAnno { 50 // 创建大头针模型 51 Annotation *anno = [[Annotation alloc] init]; 52 anno.title = @"传智"; 53 anno.subtitle = @"育新小区"; 54 CGFloat latitude = 36.821199 + arc4random_uniform(20); 55 CGFloat longitude = 116.858776 + arc4random_uniform(20); 56 anno.coordinate = CLLocationCoordinate2DMake(latitude , longitude); 57 anno.icon = @"category_1"; 58 59 // 添加大头针 60 [self.customMapView addAnnotation:anno]; 61 } 62 63 #pragma mark - MKMapViewDelegate 64 65 //每次更新用户的位置就会调用 66 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 67 { 68 69 //反向地理编码 70 [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { 71 CLPlacemark *placeMark = [placemarks firstObject]; 72 //设置大头针显示内容 73 userLocation.title = placeMark.name; 74 userLocation.subtitle = placeMark.locality; 75 }]; 76 77 //移动地图到当前用户所在的位置 78 [self.customMapView setCenterCoordinate:userLocation.location.coordinate animated:YES]; 79 } 80 81 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation 82 { 83 //对用户当前位置的大头针特殊处理 84 if ([annotation isKindOfClass:[Annotation class]] == NO) { 85 //注意: 如果返回nil, 系统会按照自己默认的方式显示 86 return nil; 87 } 88 89 // 1.创建大头针 90 BZAnnotationView *annoView = [BZAnnotationView annotationViewWithMap:mapView]; 91 // 2.设置模型 92 annoView.annotation = annotation; 93 94 /* 95 //默认情况下MKAnnotationView是无法显示的,如果想自定义大头针可以使用其子类MKPinAnnotationView 96 //自定义大头针默认情况下,点击不会显示标题,需要我们手动显示 97 98 static NSString *identifier = @"annotation"; 99 // 1.从缓存池中取 100 MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; 101 // 2.缓存池中没有创建 102 if (!annoView) { 103 annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier]; 104 105 //设置大头针颜色 106 annoView.pinTintColor = [UIColor orangeColor]; 107 //设置大头针从天而降 108 annoView.animatesDrop = YES; 109 //设置大头针标题显示 110 annoView.canShowCallout = YES; 111 //设置大头针标题显示的偏移 112 annoView.calloutOffset = CGPointMake(0, 30); 113 //设置大头针辅助视图 114 annoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd]; 115 //设置大头针图片 116 //注意: 如果你是使用的MKPinAnnotationView创建的自定义大头针, 那么设置图片无效, 因为系统内部会做一些操作, 覆盖掉我们自己的设置 117 //annoView.image = [UIImage imageNamed:@"category_4"]; 118 119 } 120 // 3.给大头针View设置数据 121 annoView.annotation = annotation; 122 123 */ 124 125 return annoView; 126 } 127 128 129 130 #pragma mark - 懒加载 131 - (CLGeocoder *)geocoder 132 { 133 if(!_geocoder){ 134 _geocoder = [[CLGeocoder alloc] init]; 135 136 } 137 return _geocoder; 138 } 139 140 @end