iOS 地图定位-地图

地图

准备工作

  • 导入MapKit框架(iOS5之后不在需要程序员自己导入)
  • 导入主头文件#import <MapKit/MapKit.h>
  • MapKit框架中所有的数据类型的前缀都是MK。
  • MapKit有一个比较重要的UI控件:MKMapView,专门用于地图的显示
  • 设置MKMapView的userTrackingModes属性可以跟踪显示用户的当前位置
typedef NS_ENUM(NSInteger, MKUserTrackingMode) {
    MKUserTrackingModeNone = 0, // 不跟踪用户的位置
    MKUserTrackingModeFollow, //跟踪并在地图上显示用户当前的位置
    MKUserTrackingModeFollowWithHeading, //跟踪并在地图上显示用户当前的位置,地图会随着用户前进的方向进行旋转。
} NS_ENUM_AVAILABLE(NA, 5_0) __WATCHOS_PROHIBITED;
  • 可以通过设置MKMapView的mapType设置地图的类型(mapType是一个枚举值)
typedef NS_ENUM(NSUInteger, MKMapType) {
    MKMapTypeStandard = 0,//普通地图
    MKMapTypeSatellite,//卫星云图
    MKMapTypeHybrid,//普通地图覆盖于卫星云图之上
    MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0),//地形和建筑的三围模型
    MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0),显示道路和附加元素的Flyover
}

创建一个地图

  1. 在延展里声明一个地图的属性
@interface RootViewController ()<MKMapViewDelegate>
@property (strong, nonatomic)MKMapView *mapView;
@property (assign, nonatomic)CGRect frame;
@end
  1. 把这个属性写成懒加载并将它添加视图控制器的view上
-(MKMapView *)mapView{
    if (!_mapView) {
        _mapView = [[MKMapView alloc]initWithFrame:self.view.bounds];
        [self.view addSubview:_mapView];
    }return _mapView;
}
  1. 为了让地图适配屏幕的旋转,我们需要重写下面这个方法
    这个方法的返回值是一个枚举类型,返回的是支持屏幕旋转的方向
typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {
    UIInterfaceOrientationMaskPortrait//home键在下
    UIInterfaceOrientationMaskLandscapeLeft//支持向左旋转
    UIInterfaceOrientationMaskLandscapeRight//支持向右旋转
    UIInterfaceOrientationMaskPortraitUpsideDown//支持上下
    UIInterfaceOrientationMaskLandscape//支持左右同时旋转
    UIInterfaceOrientationMaskAll//支持四个方向
    UIInterfaceOrientationMaskAllButUpsideDown//支持上左右
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAll;//让旋转支持所有方向
}

使用下面的这个方法,可以监测到屏幕的旋转,在这个我们徐亚我改变地图的位置信息。
在此之前我们需要现在viewDidLoad中获取到程序启动时的位置信息

-(void)viewDidLoad{
    self.frame = self.view.frame;
}
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:
(id<UIViewControllerTransitionCoordinator>)coordinator{
    CGRect temp = CGRectMake(0, 0, 0, 0);
    if (size.width > size.height) {
        temp = CGRectMake(0, 0, self.frame.size.height, self.frame.size.width);
    }else{
        temp = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    }
    self.mapView.frame = temp;
}
  1. 设置地图的跟踪属性,以及使用的地图类型
//用户位置追踪(用户位置追踪用于标记用户当前位置,此时会调用定位服务)
self.mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
    self.mapView.mapType = MKMapTypeStandard;//普通地图
self.mapView.delegate = self;//指定代理人,下面我们需要实现一些地图和大头针的下一方法。

完成以上的四步,我们就可以在我们的模拟器上看到地图了
下面我们需要在地图上设置它的另外一个属性,大头针。

地图的代理方法

  • 当地图显示的位置发生改变,就会执行此代理方法。
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
//将得到的location信息  反地理编码成位置名称。
    NSLog(@"位置发生变化了");
    CLGeocoder *geocoder = [[CLGeocoder alloc]init];
    [geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        CLPlacemark *newPlacemark = placemarks.lastObject;
        //设置大头针的标题
        userLocation.title = newPlacemark.country;
        userLocation.subtitle = newPlacemark.name;
    }];
}
  • 地图上显示的区域即将发生改变的时候调用的方法
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated{
    NSLog(@"地图上显示的区域即将发生改变");
}
  • 地图上的位置显示的区域已经发生改变的时候调用的方法。
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    NSLog(@"地图上的位置显示的区域已经发生改变");
}

大头针

在iOS开发中经常会标记某个位置,需要使用地图标注,也就是大家俗称的“大头针”。在这里系统为我们提供了一个大头针的类MKPointAnnotation

系统的大头针

MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc]init];
    pointAnnotation.coordinate = CLLocationCoordinate2DMake(35, 108);//设置大头针的位置信息
    /**
     *  设置大头针的标题
     */
    pointAnnotation.title = @"甘家寨";//主标题
    pointAnnotation.subtitle = @"大牛夜市";//副标题
    [self.mapView addAnnotation:pointAnnotation];//将大头针添加到地图上

自定义大头针

只要一个NSObject类实现MKAnnotation协议就可以作为一个大头针,通常会重写协议中coordinate(标记位置)、title(标题)、subtitle(子标题)三个属性,然后在程序中创建大头针对象并调用addAnnotation:方法添加大头针即可(之所以iOS没有定义一个基类实现这个协议供开发者使用,多数原因应该是MKAnnotation是一个模型对象,对于多数应用模型会稍有不同,例如后面的内容中会给大头针模型对象添加其他属性)。

#import <Foundation/Foundation.h>

#import <MapKit/MapKit.h>

@interface MyAnnotation : NSObject<MKAnnotation>//遵循annotation协议
@property (assign, nonatomic)CLLocationCoordinate2D coordinate;//位置信息
@property (copy, nonatomic)NSString *title;//标题
@property (copy, nonatomic)NSString *subtitle;//副标题
@end

使用自定义的大头针

- (void)myannotation{
    MyAnnotation *annotation = [[MyAnnotation alloc]init];
    annotation.coordinate = CLLocationCoordinate2DMake(35, 107);
    annotation.title = @"大雁塔";
    annotation.subtitle = @"西安市";
    [self.mapView addAnnotation:annotation];
}

自定义大头针的协议方法

每插入一个大头针,都会执行一次代理方法。
这个方法有点类似于tableView的重用机制,能有效的节约资源。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:
(id<MKAnnotation>)annotation{
    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"insert"];
    if (!annotationView) {
        annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"insert"];
    }
    
    if ([annotation isKindOfClass:[MyAnnotation class]]) {
        annotationView.pinTintColor = [UIColor blackColor];//设置大头针的颜色
        annotationView.animatesDrop = YES;//设置从天而降的效果
        annotationView.canShowCallout = YES;//在点击大头针时是否显示标题
        annotationView.leftCalloutAccessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"2.jpeg"]];//设置大头针的左侧辅助视图
        return annotationView;
    }else{
        return nil;//当前方法返回值为nil的时候大头针保持系统的样子
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容