文档章节

​ MapKit地图

Ethan-GOGO
 Ethan-GOGO
发布于 2015/09/21 19:32
字数 1341
阅读 107
收藏 0

1 MapKit基础使用

 *** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named MKMapView'

    如果storyboard中用到了地图, 必须手动导入框架

#import <MapKit/MapKit.h>
@interface ViewController ()<MKMapViewDelegate>
/**
 *  地图
 */
@property (weak, nonatomic) IBOutlet MKMapView *customMapView;
@property (nonatomic, strong) CLLocationManager *mgr;
/**
 *  地理编码对象
 */
@property (nonatomic ,strong) CLGeocoder *geocoder;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 1.设置地图显示的类型
    /*
     typedef enum : NSUInteger {
     MKMapTypeStandard , 标准(默认)
     MKMapTypeSatellite ,卫星
     MKMapTypeHybrid 混合(标准 + 卫星)
     } MKMapType;
     */
    self.customMapView.mapType = MKMapTypeSatellite;
    
    
    //2.CoreLocation框架定位
    // 注意:在iOS8中, 如果想要追踪用户的位置, 必须自己主动请求隐私权限
    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
        // 主动请求权限
        self.mgr = [[CLLocationManager alloc] init];
        
        [self.mgr requestAlwaysAuthorization];
    }
    
    //3. 设置不允许地图旋转
    self.customMapView.rotateEnabled = NO;
    
    //4. 成为mapVIew的代理
    self.customMapView.delegate = self;
    
    //5. 如果想利用MapKit获取用户的位置, 可以追踪
    /*
     typedef NS_ENUM(NSInteger, MKUserTrackingMode) {
     MKUserTrackingModeNone = 0, 不追踪/不准确的
     MKUserTrackingModeFollow, 追踪
     MKUserTrackingModeFollowWithHeading, 追踪并且获取用的方向
     }
     */
    self.customMapView.userTrackingMode =  MKUserTrackingModeFollow;
    
    
}

#pragma MKMapViewDelegate
/**
 *  每次更新到用户的位置就会调用(调用不频繁, 只有位置改变才会调用)
 *  @param userLocation 大头针模型
 */
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    /*
     地图上蓝色的点就称之为大头针
     大头针可以拥有标题/子标题/位置信息
     大头针上显示什么内容由大头针模型确定(MKUserLocation)
     */
    
    //1.设置大头针内容
    // 利用反地理编码获取位置之后设置标题
    [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *placemark = [placemarks firstObject];
        NSLog(@"获取地理位置成功 name = %@ locality = %@", placemark.name, placemark.locality);
        userLocation.title = placemark.name;
        userLocation.subtitle = placemark.locality;
    }];
    
    
    //2.设置大头针显示范围
    // 移动地图到当前用户所在位置。
//    [self.customMapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
    
    //3. 设置地图显示的区域,也会移动地图到当前用户所在位置
    // 获取用户的位置
    CLLocationCoordinate2D center = userLocation.location.coordinate;
    // 指定经纬度的跨度
    MKCoordinateSpan span = MKCoordinateSpanMake(0.009310,0.007812);
    // 将用户当前的位置作为显示区域的中心点, 并且指定需要显示的跨度范围
    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
    // 设置显示区域
    [self.customMapView setRegion:region animated:YES];
}


//- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated

/**
 *  地图的区域改变完成时调用。通常用来获取显示范围的经纬度。
 *  1度等于110km
 */
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    NSLog(@"地图的区域改变完成时调用");
    
    // 0.119170 0.100000
    // 0.238531 0.200156
    // 0.009310 0.007812
    NSLog(@"%f %f", self.customMapView.region.span.latitudeDelta, self.customMapView.region.span.longitudeDelta);
}

#pragma mark - 懒加载
- (CLGeocoder *)geocoder
{
    if (!_geocoder) {
        _geocoder = [[CLGeocoder alloc] init];
    }
    return _geocoder;
}

2 自定义大头针

**
**要在1,基础使用的前提下自定义

//添加数据到模型中
- (IBAction)addAnno {
    // 创建大头针模型
    HMAnnotation *anno = [[HMAnnotation alloc] init];
    anno.title = @"传智";
    anno.subtitle = @"育新小区";
    CGFloat latitude = 36.821199 + arc4random_uniform(20);
    CGFloat longitude = 116.858776 + arc4random_uniform(20);
    anno.coordinate = CLLocationCoordinate2DMake(latitude , longitude);
    anno.icon = @"category_1";
    
    // 添加大头针
    [self.customMapView addAnnotation:anno];
    
    
    // 创建大头针模型
    HMAnnotation *anno2 = [[HMAnnotation alloc] init];
    anno2.title = @"传智2";
    anno2.subtitle = @"育新小区2";
    CGFloat latitude2 = 36.821199 + arc4random_uniform(20);
    CGFloat longitude2 = 116.858776 + arc4random_uniform(20);
    anno2.coordinate = CLLocationCoordinate2DMake(latitude2 , longitude2);
    anno2.icon = @"category_2";
    
    // 添加大头针
    [self.customMapView addAnnotation:anno2];
}



//添加多少次数据到annotation,就会调用多少次这个代理方法
#pragma MKMapViewDelegate
/**
 *  每次添加大头针就会调用(地图上有几个大头针就调用几次)
 *
 *  @param mapView    地图
 *  @param annotation 大头针模型
 *
 *  @return 大头针的view
 */
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{

    // 对用户当前的位置的大头针特殊处理,定位位置大头针不变
    // 注意: 如果return nil, 系统会按照自己默认的方式显示
    if ([annotation isKindOfClass:[HMAnnotation class]] == NO) {
        return nil;
    }
    
    static NSString *identifier = @"anno";
    
    /* 1.从缓存池中取
       2.如果缓存池中没有, 创建一个新的
         1>注意: 默认情况下MKAnnotationView是无法显示的,除非使用图标图片属性,否则想自定义大头针可以使用MKAnnotationView的子类MKPinAnnotationView
         2>.注意: 如果是自定义的大头针, 默认情况点击大头针之后是不会显示标题的, 需要我们自己手动设置显示,要设置annoView.canShowCallout = YES;
        
     //强制转换为子类
       MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
     
     //两个MKPinAnnotationView的特有属性
       annoView.pinColor = MKPinAnnotationColorPurple; //设置大头针的颜色
        annoView.animatesDrop = YES;                   //设置大头针从天而降
    */
    
    
    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    if (annoView == nil) {
        annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier];
        annoView = [[MKAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier];

        
        // 设置大头针标题是否显示
        annoView.canShowCallout = YES;
        
        // 设置大头针标题显示的偏移位
        annoView.calloutOffset = CGPointMake(0, 0);
        
        // 设置大头针左边的辅助视图
        annoView.leftCalloutAccessoryView = [[UISwitch alloc] init];
        // 设置大头针右边的辅助视图
        annoView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
      
    }
    
    // 设置大头针的图片
    // 注意: 如果你是使用的MKPinAnnotationView创建的自定义大头针, 那么设置图片无效, 因为系统内部会做一些操作, 覆盖掉我们自己的设置
    HMAnnotation *anno = (HMAnnotation *)annotation;
    annoView.image = [UIImage imageNamed:anno.icon];
    
    // 3.给大头针View设置数据
    annoView.annotation = annotation;
    
    // 4.返回大头针View
    return annoView;
    
}
//
/************以下方法是封装MKAnnotationView(没有涉及到它的子类MKPinAnnotationView),类似与tableView的cell*************/
#import "HMAnnotationView.h"
#import "HMAnnotation.h"    //数据模型

@implementation HMAnnotationView

//初始化
- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
        // 初始化
        // 设置大头针标题是否显示
        self.canShowCallout = YES;
        
        // 设置大头针左边的辅助视图
        self.leftCalloutAccessoryView = [[UISwitch alloc] init];
        
        // 设置大头针右边的辅助视图
        self.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
    }
    return self;
}

+ (instancetype)annotationViewWithMap:(MKMapView *)mapView
{
    static NSString *identifier = @"anno";
    
    // 1.从缓存池中取
    HMAnnotationView *annoView = (HMAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    // 2.如果缓存池中没有, 创建一个新的
    if (annoView == nil) {
        
        annoView = [[HMAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier];
    }
    
    return annoView;
}

//- (void)setAnnotation:(id<MKAnnotation>)annotation
- (void)setAnnotation:(HMAnnotation *)annotation
{
    [super setAnnotation:annotation];
    
    //     处理自己特有的操作
    self.image = [UIImage imageNamed:annotation.icon];
    
}



© 著作权归作者所有

上一篇: NSAttributedString
下一篇: CoreLocation定位
Ethan-GOGO
粉丝 13
博文 174
码字总数 82033
作品 0
广州
私信 提问
【高德API】如何利用MapKit开发全英文检索的iOS地图

制作全英文地图的展示并不困难,但是要制作全英文的数据检索列表,全英文的信息窗口,你就没办法了吧。告诉你,我有妙招!使用iOS自带的MapKit来展示全球英文底图,结合上高德API的中英文检索...

酸奶小妹GIS
2015/01/06
0
0
iOS 定位和地图

一、定位 1.1 定位概要 要实现地图、导航功能,往往需要先熟悉定位功能,在iOS中通过Core Location框架进行定位操作。Core Location自⾝可以单独使用,和地图开发框架MapKit完全是独立的,但是往...

从訫开始_倾深爱
2016/09/08
45
0
iOS 设备判断是否安装相关地图(百度、高德。。。)

最近项目关于地图的,和朋友一起做的,他们用的高德地图,他做到半路有事,我来接手,结果我手机上没有安装高德地图,到我这边点击导航没啥反应,后来就查了一下,简单处理下,最终实现以下的...

JustEverOnce
2018/01/10
0
0
iOS 高德地图定位及地理反编码的简明教程

最终效果图: 一, plist及frame的配置 1 ,info.plist文件中添加 Privacy - Location When In Use Usage Description(需要时开启定位,另一个是Privacy - Location Always Usage Descripti...

AustinKuture
2016/10/21
288
0
objective-c CLGeocoder 自带地图应用 路径导航

// // ViewController.m // 自带地图应用 路径导航 // // Created by DC017 on 15/12/24. // Copyright © 2015年 DC017. All rights reserved. // #import "ViewController.h" #import <Cor......

_pioneer_
2015/12/24
41
0

没有更多内容

加载失败,请刷新页面

加载更多

哪些情况下适合使用云服务器?

我们一直在说云服务器价格适中,具备弹性扩展机制,适合部署中小规模的网站或应用。那么云服务器到底适用于哪些情况呢?如果您需要经常原始计算能力,那么使用独立服务器就能满足需求,因为他...

云漫网络Ruan
今天
5
0
Java 中的 String 有没有长度限制

转载: https://juejin.im/post/5d53653f5188257315539f9a String是Java中很重要的一个数据类型,除了基本数据类型以外,String是被使用的最广泛的了,但是,关于String,其实还是有很多东西...

低至一折起
今天
17
0
OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
11
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
9
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部