iOS 地图定位-地图

地图

准备工作

  • 导入MapKit框架(iOS5之后不在需要程序员自己导入)
  • 导入主头文件#import
  • 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 ()
@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)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 * _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 

#import 

@interface MyAnnotation : NSObject//遵循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)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的时候大头针保持系统的样子
    }
}

你可能感兴趣的:(iOS 地图定位-地图)