• 地图篇-03.展示地图


    地图篇-03.展示地图

    这一小节是地图展示,在这一小节要接触到一个框架:MapKit

    1.展示地图

    展示地图特别简单,就是调用系统的地图,有两种方式,直接上代码

    第一种方式:

    导入头文件

    #import <MapKit/MapKit.h>

    然后输入以下代码:

    1 //    1.代码展示地图
    2     MKMapView *mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
    3     
    4     [self.view addSubview:mapView];

    运行可见:

    细心的朋友能开到地图右下角有一个高德地图,这是苹果自带的框架使用的数据是高德的,但是在国外的话就不会显示这个,可以去试试改IP显示.

    第二种方法:

    通过storyboard来创建

    自动布局前面说过了,这里就不讲了.

    注意在使用storyboard拖入mapView的时候,需要导入框架和头文件

    运行得到同样的效果.

    2.用户位置(蓝色小圆点)

    前面已经讲到了用户位置,这里不多讲,直接上代码

     1 //
     2 //  ViewController.m
     3 //  03.展示地图
     4 //
     5 //  Created by admin on 16/5/25.
     6 //  Copyright © 2016年 KXZDJ. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 #import <MapKit/MapKit.h>
    11 
    12 @interface ViewController ()
    13 @property (weak, nonatomic) IBOutlet MKMapView *mapView;
    14 //这里没有导入CLLocation头文件的原因是MapKit包含了
    15 @property (nonatomic, strong) CLLocationManager *mgr;
    16 
    17 @end
    18 
    19 @implementation ViewController
    20 
    21 -(CLLocationManager *)mgr {
    22     if (!_mgr) {
    23         _mgr = [[CLLocationManager alloc] init];
    24         //这里不需要用到代理方法,所以不设置代理
    25     }
    26     return _mgr;
    27 }
    28 
    29 - (void)viewDidLoad {
    30     [super viewDidLoad];
    31     //获取用户位置
    32     self.mapView.showsUserLocation = YES;
    33     //请求用户授权,然后在info.plist文件里面配置字段NSLocationAlwaysUsageDescription
    34     //这里我就不判断了,直接添加always字段.
    35     [self.mgr requestAlwaysAuthorization];
    36     
    37 }
    38 
    39 - (void)didReceiveMemoryWarning {
    40     [super didReceiveMemoryWarning];
    41     // Dispose of any resources that can be recreated.
    42 }
    43 
    44 @end

    运行效果:

    现在就能看到地图上的蓝色小圆点了,但是:

    点击小圆点弹出的提示框只显示了一个current location,能不能显示当前位置呢?肯定可以的啦,这里就要用到地理编码的知识了.

    因为我们能获取到用户位置,就可以通过反地理编码,把他转换成当前位置.通过mapView的代理方法,显示出来.

    3.用户详细地址

    代码:

     1 //
     2 //  ViewController.m
     3 //  03.展示地图
     4 //
     5 //  Created by admin on 16/5/25.
     6 //  Copyright © 2016年 KXZDJ. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 #import <MapKit/MapKit.h>
    11 
    12 @interface ViewController ()<MKMapViewDelegate>
    13 @property (weak, nonatomic) IBOutlet MKMapView *mapView;
    14 //这里没有导入CLLocation头文件的原因是MapKit包含了
    15 @property (nonatomic, strong) CLLocationManager *mgr;
    16 
    17 @end
    18 
    19 @implementation ViewController
    20 
    21 -(CLLocationManager *)mgr {
    22     if (!_mgr) {
    23         _mgr = [[CLLocationManager alloc] init];
    24         //这里不需要用到代理方法,所以不设置代理
    25     }
    26     return _mgr;
    27 }
    28 
    29 - (void)viewDidLoad {
    30     [super viewDidLoad];
    31     //获取用户位置
    32     self.mapView.showsUserLocation = YES;
    33     //请求用户授权,然后在info.plist文件里面配置字段NSLocationAlwaysUsageDescription
    34     //这里我就不判断了,直接添加always字段.
    35     [self.mgr requestAlwaysAuthorization];
    36     //设置代理
    37     self.mapView.delegate = self;
    38 }
    39 
    40 - (void)didReceiveMemoryWarning {
    41     [super didReceiveMemoryWarning];
    42     // Dispose of any resources that can be recreated.
    43 }
    44 /**
    45  *  当用户位置更新的时候调用
    46  *
    47  *  @param mapView      当前地图
    48  *  @param userLocation 用户位置
    49  */
    50 -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    51     //反地理编码
    52     CLGeocoder *reverseGeo = [[CLGeocoder alloc] init];
    53     //MKUserLocation-userLocation的属性
    54     /*
    55      // 如果用户的位置正在更新,返回YES.
    56      @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
    57      
    58      // 如果MKMapView.showsUserLocation=NO或者用户的位置尚未确定,返回nil.
    59      @property (readonly, nonatomic, nullable) CLLocation *location;
    60      
    61      // 如果不适用MKUserTrackingModeFollowWithHeading返回nil;
    62      @property (readonly, nonatomic, nullable) CLHeading *heading NS_AVAILABLE(10_9, 5_0);
    63      
    64      // 描述用户当前位置的文本.
    65      @property (nonatomic, copy, nullable) NSString *title;
    66      
    67      // 描述用户当前位置的详细信息.
    68      @property (nonatomic, copy, nullable) NSString *subtitle;
    69      */
    70     [reverseGeo reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    71         //判断,如果返回的地标为空,或者error存在的时候
    72         if (placemarks.count == 0 || error) {
    73             NSLog(@"地理编码失败");
    74             return;
    75         }
    76         
    77         
    78         
    79         //根据userLocation.location进行反地理编码获得的地址只有一个(地理编码小节中有讲)
    80         CLPlacemark *clp = [placemarks firstObject];
    81         //设置用户当前位置的地址
    82         userLocation.title = clp.name;
    83         //设置用户当前位置的详细信息
    84         userLocation.subtitle = @"那小子真帅...";//这里可以打印街道,门牌号等等,这里举例.
    85         
    86         
    87     }];
    88     
    89 }
    90 
    91 @end

    运行效果图:

    还好没有打脸.- -!

    4.地图显示范围(经纬度跨度)

    上面的地图中,显示了整个亚洲,但是我们平时使用的时候肯定想他自己定位在我们所在的城市,现在我想要改变一下这个跨度,有招!

      mapView有个方法:设置区域范围

        self.mapView setRegion:(MKCoordinateRegion)

    他需要一个MKCoordinateRegion类型的参数,看不懂?没事,command+左键点进去,会看到如下图:

    一个结构体,里面两个参数,一个CLLocationCoordinate类型的,这个我们前面讲过,坐标嘛,经纬度,所以这里的center就是把用户的经纬度用来当中心点.另外一个MKCoordinateSpan类型的,不知道?再点进去:

    又是一个结构体,里面也有两个参数,首先,span:范围,宽度的意思.latitudeDelta是纬度的跨度,longitudeDelta是经度的跨度.

    大概了解了之后,上代码:

      1 //
      2 //  ViewController.m
      3 //  03.展示地图
      4 //
      5 //  Created by admin on 16/5/25.
      6 //  Copyright © 2016年 KXZDJ. All rights reserved.
      7 //
      8 
      9 #import "ViewController.h"
     10 #import <MapKit/MapKit.h>
     11 
     12 @interface ViewController ()<MKMapViewDelegate>
     13 @property (weak, nonatomic) IBOutlet MKMapView *mapView;
     14 //这里没有导入CLLocation头文件的原因是MapKit包含了
     15 @property (nonatomic, strong) CLLocationManager *mgr;
     16 
     17 @end
     18 
     19 @implementation ViewController
     20 
     21 -(CLLocationManager *)mgr {
     22     if (!_mgr) {
     23         _mgr = [[CLLocationManager alloc] init];
     24         //这里不需要用到代理方法,所以不设置代理
     25     }
     26     return _mgr;
     27 }
     28 
     29 - (void)viewDidLoad {
     30     [super viewDidLoad];
     31     //获取用户位置
     32     self.mapView.showsUserLocation = YES;
     33     //请求用户授权,然后在info.plist文件里面配置字段NSLocationAlwaysUsageDescription
     34     //这里我就不判断了,直接添加always字段.
     35     [self.mgr requestAlwaysAuthorization];
     36     //设置代理
     37     self.mapView.delegate = self;
     38     
     39     //中心点
     40     CLLocationCoordinate2D center = CLLocationCoordinate2DMake(30.67, 104.06);
     41     //跨度
     42     MKCoordinateSpan span = MKCoordinateSpanMake(1.0, 1.0);
     43     //范围
     44     MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
     45     
     46     //地图范围
     47     [self.mapView setRegion:region];
     48     
     49 }
     50 
     51 - (void)didReceiveMemoryWarning {
     52     [super didReceiveMemoryWarning];
     53     // Dispose of any resources that can be recreated.
     54 }
     55 /**
     56  *  当用户位置更新的时候调用
     57  *
     58  *  @param mapView      当前地图
     59  *  @param userLocation 用户位置
     60  */
     61 -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
     62     //反地理编码
     63     CLGeocoder *reverseGeo = [[CLGeocoder alloc] init];
     64     //MKUserLocation-userLocation的属性
     65     /*
     66      // 如果用户的位置正在更新,返回YES.
     67      @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
     68      
     69      // 如果MKMapView.showsUserLocation=NO或者用户的位置尚未确定,返回nil.
     70      @property (readonly, nonatomic, nullable) CLLocation *location;
     71      
     72      // 如果不适用MKUserTrackingModeFollowWithHeading返回nil;
     73      @property (readonly, nonatomic, nullable) CLHeading *heading NS_AVAILABLE(10_9, 5_0);
     74      
     75      // 描述用户当前位置的文本.
     76      @property (nonatomic, copy, nullable) NSString *title;
     77      
     78      // 描述用户当前位置的详细信息.
     79      @property (nonatomic, copy, nullable) NSString *subtitle;
     80      */
     81     [reverseGeo reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
     82         //判断,如果返回的地标为空,或者error存在的时候
     83         if (placemarks.count == 0 || error) {
     84             NSLog(@"地理编码失败");
     85             return;
     86         }
     87         
     88         
     89         
     90         //根据userLocation.location进行反地理编码获得的地址只有一个(地理编码小节中有讲)
     91         CLPlacemark *clp = [placemarks firstObject];
     92         //设置用户当前位置的地址
     93         userLocation.title = clp.name;
     94         //设置用户当前位置的详细信息
     95         userLocation.subtitle = @"那小子真帅...";//这里可以打印街道,门牌号等等,这里举例.
     96         
     97         
     98     }];
     99     
    100 }
    101 
    102 @end

    运行效果如下:

    在上面代码中第42行,我们不知道这个范围应该是多少,不用急,有两个代理方法能带我们装X带我们飞.

    代码:

     1 /**
     2  *  地图的范围已经改变的时候调用
     3  */
     4 -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
     5     //纬度的跨度
     6     CLLocationDegrees latitudeDelta = mapView.region.span.latitudeDelta;
     7     //经度的跨度
     8     CLLocationDegrees longitudeDelta = mapView.region.span.longitudeDelta;
     9     
    10     NSLog(@"纬度的跨度:%f,经度的跨度:%f",latitudeDelta,longitudeDelta);
    11 }
    12 /**
    13  *  地图的范围将要改变的时候调用
    14  */
    15 -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    16     
    17 }

    这两个方法中能获取到当前地图的跨度,在模拟器上按住option键然后左键上下滑动,会看到打印如下:

    可以自己试一下.

    但是这种方法有点麻烦,要获取坐标等一系列操作,下面介绍一种方法,利用mapView的一个属性userTrackingMode

    代码:

      1 //
      2 //  ViewController.m
      3 //  03.展示地图
      4 //
      5 //  Created by admin on 16/5/25.
      6 //  Copyright © 2016年 KXZDJ. All rights reserved.
      7 //
      8 
      9 #import "ViewController.h"
     10 #import <MapKit/MapKit.h>
     11 
     12 @interface ViewController ()<MKMapViewDelegate>
     13 @property (weak, nonatomic) IBOutlet MKMapView *mapView;
     14 //这里没有导入CLLocation头文件的原因是MapKit包含了
     15 @property (nonatomic, strong) CLLocationManager *mgr;
     16 
     17 @end
     18 
     19 @implementation ViewController
     20 
     21 -(CLLocationManager *)mgr {
     22     if (!_mgr) {
     23         _mgr = [[CLLocationManager alloc] init];
     24         //这里不需要用到代理方法,所以不设置代理
     25     }
     26     return _mgr;
     27 }
     28 
     29 - (void)viewDidLoad {
     30     [super viewDidLoad];
     31     //获取用户位置
     32     self.mapView.showsUserLocation = YES;
     33     //请求用户授权,然后在info.plist文件里面配置字段NSLocationAlwaysUsageDescription
     34     //这里我就不判断了,直接添加always字段.
     35     [self.mgr requestAlwaysAuthorization];
     36     //设置代理
     37     self.mapView.delegate = self;
     38     
     39     
     40     
     41     
     42     //跟踪用户位置(系统会自动给你设置一个比较合适的范围)
     43     self.mapView.userTrackingMode = MKUserTrackingModeFollow;
     44     
     45     //中心点
     46 //    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(30.67, 104.06);
     47 //    //跨度
     48 //    MKCoordinateSpan span = MKCoordinateSpanMake(1.0, 1.0);
     49 //    //范围
     50 //    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
     51 //    
     52 //    //地图范围
     53 //    [self.mapView setRegion:region];
     54     
     55 }
     56 
     57 - (void)didReceiveMemoryWarning {
     58     [super didReceiveMemoryWarning];
     59     // Dispose of any resources that can be recreated.
     60 }
     61 /**
     62  *  当用户位置更新的时候调用
     63  *
     64  *  @param mapView      当前地图
     65  *  @param userLocation 用户位置
     66  */
     67 -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
     68     //反地理编码
     69     CLGeocoder *reverseGeo = [[CLGeocoder alloc] init];
     70     //MKUserLocation-userLocation的属性
     71     /*
     72      // 如果用户的位置正在更新,返回YES.
     73      @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
     74      
     75      // 如果MKMapView.showsUserLocation=NO或者用户的位置尚未确定,返回nil.
     76      @property (readonly, nonatomic, nullable) CLLocation *location;
     77      
     78      // 如果不适用MKUserTrackingModeFollowWithHeading返回nil;
     79      @property (readonly, nonatomic, nullable) CLHeading *heading NS_AVAILABLE(10_9, 5_0);
     80      
     81      // 描述用户当前位置的文本.
     82      @property (nonatomic, copy, nullable) NSString *title;
     83      
     84      // 描述用户当前位置的详细信息.
     85      @property (nonatomic, copy, nullable) NSString *subtitle;
     86      */
     87     [reverseGeo reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
     88         //判断,如果返回的地标为空,或者error存在的时候
     89         if (placemarks.count == 0 || error) {
     90             NSLog(@"地理编码失败");
     91             return;
     92         }
     93         
     94         
     95         
     96         //根据userLocation.location进行反地理编码获得的地址只有一个(地理编码小节中有讲)
     97         CLPlacemark *clp = [placemarks firstObject];
     98         //设置用户当前位置的地址
     99         userLocation.title = clp.name;
    100         //设置用户当前位置的详细信息
    101         userLocation.subtitle = @"那小子真帅...";//这里可以打印街道,门牌号等等,这里举例.
    102         
    103         
    104     }];
    105     
    106 }
    107 
    108 /**
    109  *  地图的范围已经改变的时候调用
    110  */
    111 -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    112     //纬度的跨度
    113     CLLocationDegrees latitudeDelta = mapView.region.span.latitudeDelta;
    114     //经度的跨度
    115     CLLocationDegrees longitudeDelta = mapView.region.span.longitudeDelta;
    116     
    117     NSLog(@"纬度的跨度:%f,经度的跨度:%f",latitudeDelta,longitudeDelta);
    118 }
    119 /**
    120  *  地图的范围将要改变的时候调用
    121  */
    122 -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    123     
    124 }
    125 @end

    运行效果图:

    使用这个属性,系统会自动给你选择一个合适的范围.

    好了,展示地图小节就到此为止了,大家如果觉得有什么问题或者哪里不足都可以告诉我.谢谢

  • 相关阅读:
    “终身幼儿园”:学习是一个创造的过程
    我对ERP实质的理解(陈启申)
    Java学习记录1java并发编程之synchronized初学
    谈谈你对Spring的理解
    java中的==与equals的区别
    Windows下编译安装perl Module
    win系统用virtualBox安装Ubuntu虚拟机,如何共享数据
    Windows下emacsw3m设置代理
    自我介绍
    document 对象
  • 原文地址:https://www.cnblogs.com/Xebdison/p/5528873.html
Copyright © 2020-2023  润新知