zoukankan      html  css  js  c++  java
  • IOS-MapKit

    一、MapKit框架的使用

    MapKit框架使用须知
    MapKit框架中所有数据类型的前缀都是MK
    MapKit有一个比较重要的UI控件 :MKMapView,专门用于地图显示
     
    跟踪显示用户的位置
    设置MKMapView的userTrackingMode属性可以跟踪显示用户的当前位置
    MKUserTrackingModeNone :不跟踪用户的位置
    MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置
    MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转
     
    二、地图的类型
    可以通过设置MKMapView的mapViewType设置地图类型
    MKMapTypeStandard :普通地图
    MKMapTypeSatellite :卫星云图 
    MKMapTypeHybrid :普通地图覆盖于卫星云图之上
     
    三、MKMapView的代理
    MKMapView可以设置一个代理对象,用来监听地图的相关行为
     
    常见的代理方法有
    - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;
    一个位置更改默认只会调用一次,不断监测用户的当前位置
    每次调用,都会把用户的最新位置(userLocation参数)传进来
     
    - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;
    地图的显示区域即将发生改变的时候调用
     
    - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
    地图的显示区域已经发生改变的时候调用
     
    四、MKUserLocation
    MKUserLocation其实是个大头针模型,包括以下属性
    @property (nonatomic, copy) NSString *title;
    显示在大头针上的标题
     
    @property (nonatomic, copy) NSString *subtitle;
    显示在大头针上的子标题
    @property (readonly, nonatomic) CLLocation *location;
    地理位置信息(大头针钉在什么地方?)
     
     
    五、设置地图的显示
    通过MKMapView的下列方法,可以设置地图显示的位置和区域
    设置地图的中心点位置
    @property (nonatomic) CLLocationCoordinate2D centerCoordinate;
    - (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
     
    设置地图的显示区域
    @property (nonatomic) MKCoordinateRegion region;
    - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
     
    六、MKCoordinateRegion
    MKCoordinateRegion是一个用来表示区域的结构体,定义如下

    typedef struct {

                        CLLocationCoordinate2D center; // 区域的中心点位置

            MKCoordinateSpan span; // 区域的跨度

    } MKCoordinateRegion;

    MKCoordinateSpan的定义

    typedef struct {

        CLLocationDegrees latitudeDelta; // 纬度跨度

        CLLocationDegrees longitudeDelta; // 经度跨度

    } MKCoordinateSpan;

    七、大头针

    1.大头针的基本操作

    添加一个大头针
    - (void)addAnnotation:(id <MKAnnotation>)annotation;
     
    添加多个大头针
    - (void)addAnnotations:(NSArray *)annotations;
     
    移除一个大头针
    - (void)removeAnnotation:(id <MKAnnotation>)annotation;
     
    移除多个大头针
    - (void)removeAnnotations:(NSArray *)annotations;
     
    (id <MKAnnotation>)annotation参数是什么东西?
    大头针模型对象:用来封装大头针的数据,比如大头针的位置、标题、子标题等数据

    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

     
    3.添加大头针

    MJTuangouAnnotation *anno = [[MJTuangouAnnotation alloc] init];

    anno.title = @"传智播客iOS学院";

    anno.subtitle = @"全部课程15折,会员20折,老学员30折";

    anno.coordinate = CLLocationCoordinate2DMake(40, 116);

    [self.mapView addAnnotation:anno];

    八、自定义大头针

    1.如何自定义大头针
    设置MKMapView的代理
    实现下面的代理方法,返回大头针控件

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;

    根据传进来的(id <MKAnnotation>)annotation参数创建并返回对应的大头针控件
     
    代理方法的使用注意
    如果返回nil,显示出来的大头针就采取系统的默认样式
    标识用户位置的蓝色发光圆点,它也是一个大头针,当显示这个大头针时,也会调用代理方法
    因此,需要在代理方法中分清楚(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

    地图上的大头针控件是MKAnnotationView
     
    MKAnnotationView的属性
    @property (nonatomic, strong) id <MKAnnotation> annotation;
    大头针模型
     
    @property (nonatomic, strong) UIImage *image;
    显示的图片
     
    @property (nonatomic) BOOL canShowCallout;
    是否显示标注
     
    @property (nonatomic) CGPoint calloutOffset;
    标注的偏移量
     
    @property (strong, nonatomic) UIView *rightCalloutAccessoryView;
    标注右边显示什么控件
    @property (strong, nonatomic) UIView *leftCalloutAccessoryView;
    标注左边显示什么控件
     
    MKPinAnnotationView是MKAnnotationView的子类
     
    MKPinAnnotationView比MKAnnotationView多了2个属性
    @property (nonatomic) MKPinAnnotationColor pinColor;
    大头针颜色
     
    @property (nonatomic) BOOL animatesDrop;
    大头针第一次显示时是否从天而降

    代码

      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
  • 相关阅读:
    $NOIP2012$ 题解报告
    $NOIP2011$ 题解报告
    $NOIP2007$ 题解报告
    $NOIP2006$ 题解报告
    $NOIP2005$ 题解报告
    $NOIP2003$ 题解报告
    $NOIP2002$ 题解报告
    $NOIP2001$ 题解报告
    $NOIP2000$ 题解报告
    $NOIP1999$ 题解报告
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5350212.html
Copyright © 2011-2022 走看看