zoukankan      html  css  js  c++  java
  • 地图篇-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

    运行效果图:

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

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

  • 相关阅读:
    【leetcode】416. Partition Equal Subset Sum
    【leetcode】893. Groups of Special-Equivalent Strings
    【leetcode】892. Surface Area of 3D Shapes
    【leetcode】883. Projection Area of 3D Shapes
    【leetcode】140. Word Break II
    【leetcode】126. Word Ladder II
    【leetcode】44. Wildcard Matching
    【leetcode】336. Palindrome Pairs
    【leetcode】354. Russian Doll Envelopes
    2017.12.22 英语面试手记
  • 原文地址:https://www.cnblogs.com/Xebdison/p/5528873.html
Copyright © 2011-2022 走看看