• iOS MapKit地图


      地图框架:#import <MapKit/MapKit.h>

      基本属性和方法:

      属性:

    • 地图类视图:MKMapView
    • 地图类型:MKMapType mapType
    • 地图旋转:rotateEnabled
    • 用户追踪:MKUserTrackingMode  userTrackingMode
    • 地图区域:MKCoordinateRegion  region
    • 地图代理方法:MKMapViewDelegate
    • 用户位置类:MKUserLocation
    • 大头针类:MKAnnotation
    • 请求用户授权:requestAlwaysAuthorization

      方法:

    • 地图的区域改变完成时调用:

      - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

    • 每次更新到用户的位置就会调用(调用不频繁, 只有位置改变才会调用):

      - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation

    • 每次添加大头针就会调用(地图上有几个大头针就调用几次):

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

      

      MapKit方法的基本实现:

      A、添加地图,并且更新到用户位置

      1 #import "ViewController.h"
      2 #import <MapKit/MapKit.h>
      3 
      4 @interface ViewController ()<MKMapViewDelegate>
      5 //  地图
      6 @property (nonatomic,strong) MKMapView *mapView;
      7 @property (nonatomic, strong) CLLocationManager *mgr;
      8 // 地理编码对象
      9 @property (nonatomic ,strong) CLGeocoder *geocoder;
     10 @end
     11 
     12 @implementation ViewController
     13 
     14 // 懒加载 - mapView
     15 - (MKMapView *)mapView
     16 {
     17     if (!_mapView){
     18         
     19         _mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
     20         // 标准地图
     21           /*
     22      typedef enum : NSUInteger {
     23      MKMapTypeStandard , 标准(默认)
     24      MKMapTypeSatellite ,卫星
     25      MKMapTypeHybrid 混合(标准 + 卫星)
     26      } MKMapType;
     27      */
     28         _mapView.mapType = MKMapTypeStandard;
     29 
     30     
     31         // 追踪用户
     32           // 如果想利用MapKit获取用户的位置, 可以追踪
     33     /*
     34      typedef NS_ENUM(NSInteger, MKUserTrackingMode) {
     35      MKUserTrackingModeNone = 0, 不追踪/不准确的
     36      MKUserTrackingModeFollow, 追踪
     37      MKUserTrackingModeFollowWithHeading, 追踪并且获取用的方向
     38      }
     39      */
     40         _mapView.userTrackingMode =  MKUserTrackingModeFollow;
     41 
     42         [self.view addSubview:_mapView];
     43     }
     44     
     45     return _mapView;
     46 }
     47 
     48 #pragma mark - 懒加载
     49 - (CLGeocoder *)geocoder
     50 {
     51     if (!_geocoder) {
     52         _geocoder = [[CLGeocoder alloc] init];
     53     }
     54     return _geocoder;
     55 }
     56 
     57 
     58 - (void)viewDidLoad {
     59     [super viewDidLoad];
     60    
     61     // 注意:在iOS8中, 如果想要追踪用户的位置, 必须自己主动请求隐私权限
     62     if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
     63         // 主动请求权限
     64         self.mgr = [[CLLocationManager alloc] init];
     65         
     66         [self.mgr requestAlwaysAuthorization];
     67     }
     68     
     69   
     70     // 成为mapVIew的代理
     71     self.MapView.delegate = self;    
     72     
     73 }
     74 
     75 #pragma MKMapViewDelegate
     76 //  每次更新到用户的位置就会调用(调用不频繁, 只有位置改变才会调用)
     77 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
     78 {
     79    
     80     // 利用反地理编码获取位置之后设置标题
     81     [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {
     82         CLPlacemark *placemark = [placemarks firstObject];
     83         NSLog(@"获取地理位置成功 name = %@ locality = %@", placemark.name, placemark.locality);
     84         userLocation.title = placemark.name;
     85         userLocation.subtitle = placemark.locality;
     86     }];
     87     
     88     
     89     
     90     // 移动地图到当前用户所在位置
     91     // 获取用户当前所在位置的经纬度, 并且设置为地图的中心点
     92 //    [self.MapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
     93     
     94     // 设置地图显示的区域
     95     // 获取用户的位置
     96     CLLocationCoordinate2D center = userLocation.location.coordinate;
     97     // 指定经纬度的跨度
     98     MKCoordinateSpan span = MKCoordinateSpanMake(0.009310,0.007812);
     99     // 将用户当前的位置作为显示区域的中心点, 并且指定需要显示的跨度范围
    100     MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
    101     
    102     // 设置显示区域
    103     [self.MapView setRegion:region animated:YES];
    104 }
    105 
    106 
    107 //  地图的区域改变完成时调用
    108 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
    109 {
    110     // 获取到经纬度跨度
    111     NSLog(@"%f %f", self.MapView.region.span.latitudeDelta, self.MapView.region.span.longitudeDelta);
    112 }
    113 
    114 @end

      

      B、在地图上添加自定义的大头针:

      1. 需要自定义一个遵守MKAnnotation协议的NSObject类
      2. 需要在自定义的类中定义MKAnnotation里面的属性,同时也可以自行扩展属性
      3. 在控制器中使用自定义类添加大头针

      1、自定义大头针类:

     1 #import <Foundation/Foundation.h>
     2 #import <MapKit/MapKit.h>
     3 
     4 @interface WYSAnnotation : NSObject<MKAnnotation>
     5  //  大头针的位置
     6 @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
     7 // 大头针标题
     8 @property (nonatomic, copy) NSString *title;
     9 // 大头针的子标题
    10 @property (nonatomic, copy) NSString *subtitle;
    11 
    12 //  图标 - 自己扩展的属性
    13 @property (nonatomic, copy) NSString *icon;

      2、在ViewController中添加大头针:

     1   // 创建大头针模型
     2     WYSAnnotation *anno = [[HMAnnotation alloc] init];
     3     anno.title = @"GeekStar";
     4     anno.subtitle = @"贵在坚持";
     5     // 大头针添加在随机经纬度位置
     6     CGFloat latitude = 32.22 + arc4random_uniform(5);
     7     CGFloat longitude = 132.48 + arc4random_uniform(5);
     8     anno.coordinate = CLLocationCoordinate2DMake(latitude , longitude);
     9     anno.icon = @"hehe.jpg";
    10     
    11     // 添加大头针
    12     [self.mapView addAnnotation:anno];

      3、实现大头针的代理方法:

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
    {
    
        // 对用户当前的位置的大头针特殊处理,直接使用系统提供的大头针
        if ([annotation isKindOfClass:[HMAnnotation class]] == NO) {
            return nil;
        }
        
        // 缓存
        static NSString *identifier = @"anno";
        //缓存池中取
        // 注意: 默认情况下MKAnnotationView是无法显示的, 如果想自定义大头针可以使用MKAnnotationView的子类MKPinAnnotationView
        
        // 注意: 如果是自定义的大头针, 默认情况点击大头针之后是不会显示标题的, 需要我们自己手动设置显示
    //    MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
     
        MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        // 2.如果缓存池中没有, 创建一个新的
        if (annoView == nil) {
    //        annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier];
            annoView = [[MKAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier];
            
            // 设置大头针的颜色
    //        annoView.pinColor = MKPinAnnotationColorPurple;
            
            // 设置大头针从天而降
    //        annoView.animatesDrop = YES;
            
            // 设置大头针标题是否显示
            annoView.canShowCallout = YES;
            
            // 设置大头针标题显示的偏移位
    //        annoView.calloutOffset = CGPointMake(-50, 0);
            
            // 设置大头针左边的辅助视图
            annoView.leftCalloutAccessoryView = [[UISwitch alloc] init];
            // 设置大头针右边的辅助视图
            annoView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
          
        }
        
        // 设置大头针的图片
        // 注意: 如果你是使用的MKPinAnnotationView创建的自定义大头针, 那么设置图片无效, 因为系统内部会做一些操作, 覆盖掉我们自己的设置
    //    annoView.image = [UIImage imageNamed:@"hehe.jpg"];
        HMAnnotation *anno = (HMAnnotation *)annotation;
        annoView.image = [UIImage imageNamed:anno.icon];
        
        // 3.给大头针View设置数据
        annoView.annotation = annotation;
        
        // 4.返回大头针View
        return annoView;
         
    }

      C、ios系统自带导航:

     1 #import "ViewController.h"
     2 #import <MapKit/MapKit.h>
     3 
     4 @interface ViewController ()
     5 
     6 //  地理编码对象
     7 @property(nonatomic, strong) CLGeocoder *geocoder;
     8 @end
     9 
    10 @implementation ViewController
    11 
    12 #pragma mark - 懒加载
    13 - (CLGeocoder *)geocoder
    14 {
    15     if (!_geocoder) {
    16         self.geocoder = [[CLGeocoder alloc] init];
    17     }
    18     return _geocoder;
    19 }
    20 
    21 
    22 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    23 {
    24     // 获取用户输入的起点和终点
    25     NSString *startStr = @"上海";
    26     NSString *endStr = @"北京";
    27     
    28 
    29     // 地理编码
    30     [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) {
    31         if (placemarks.count == 0) return;
    32         
    33         // 开始位置的地标
    34         CLPlacemark *startCLPlacemark = [placemarks firstObject];
    35         
    36         
    37         // 地理编码
    38         [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) {
    39             
    40             if (placemarks.count == 0) return;
    41             
    42             // 结束位置的地标
    43             CLPlacemark *endCLPlacemark = [placemarks firstObject];
    44             
    45             // 开始导航
    46             [self startNavigationWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark];
    47         }];
    48         
    49     }];
    50 }
    51 
    52 //  开始导航
    53 - (void)startNavigationWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark
    54 {
    55 
    56     //创建起点
    57     MKPlacemark *startPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark];
    58     MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startPlacemark];;
    59     
    60     //创建终点
    61     MKPlacemark *endPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark];
    62     MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endPlacemark];
    63     
    64     // 设置数组
    65     NSArray *items = @[startItem, endItem];
    66     
    67     
    68     // 设置属性
    69     NSMutableDictionary *options = [NSMutableDictionary dictionary];
    70     // 模式
    71     options[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving;
    72     
    73     // 开启系统导航
    74     [MKMapItem openMapsWithItems:items launchOptions:options];
    75 }
    76 
    77 
    78 @end
    欢迎加QQ群交流: iOS: 279096195 React Native: 482205185
  • 相关阅读:
    轻松把你的项目升级到PWA
    聊聊React高阶组件(Higher-Order Components)
    java NIO系列教程2
    java NIO系列教程1
    个人笔记
    onclick时间加return和不加return的区别
    URL编码分析与乱码解决方案
    第九天 1-8 RHEL7软件包管理
    第八天 RHEL7.2 文件权限管理(第一部分)
    第七天 Linux用户管理、RHEL6.5及RHEL7.2 root密码破解、RHEL6.5安装vmware tools
  • 原文地址:https://www.cnblogs.com/GeekStar/p/4452837.html
Copyright © 2020-2023  润新知