iOS - MapKit

2018-07-30  本文已影响17人  CDLOG

苹果自带的地图是高德地图

1,准备

0,先获得位置信息授权,参考文章链接https://www.jianshu.com/p/381c5bc950a6
1,导入头文件#import <MapKit/MapKit.h>
2,拖入MKMapView控件
3,选择地图类型self.customMapView.mapType = MKMapTypeStandard;

2,基本设置

// 1.设置地图显示类型
    /**
     MKMapTypeStandard = 0,  // 标准
     MKMapTypeSatellite,     // 卫星
     MKMapTypeHybrid,        // 混合(标准+卫星)
     MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0), // 3D立体卫星
     MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0), // 3D立体混合
     */
    self.customMapView.mapType = MKMapTypeStandard;
// 2.设置地图的跟随模式
    //(注意:设置此属性会使用到用户的位置隐私,所以需要请求用户授权,否则没有效果)
    /**
        MKUserTrackingModeNone = 0, // 不跟随
        MKUserTrackingModeFollow, // 跟随用户位置
        MKUserTrackingModeFollowWithHeading, // 跟随用户位置,并跟随用户方向
     */
    self.customMapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;


// 3.设置地图其它属性(操作)
    /** 注意:设置对应的属性时,注意该属性是从哪个系统版本开始引入的,做好不同系统版本的适配*/
    // 是否可以缩放
    self.customMapView.zoomEnabled = YES;
    // 是否可以滚动
    self.customMapView.scrollEnabled = YES;
    // 是否可以旋转
    self.customMapView.rotateEnabled = YES;
    // 是否显示3D
    self.customMapView.pitchEnabled = YES;

    // 4.设置地图其它属性(显示)
    // 是否显示指南针
    self.customMapView.showsCompass = YES;
    // 是否显示比例尺
    self.customMapView.showsScale = YES;
    // 是否显示交通
    self.customMapView.showsTraffic = YES;
    // 是否显示建筑物
    self.customMapView.showsBuildings = YES;

3,代理方法

1,用户位置信息改变时的代理

#pragma mark MKMapViewDelegate
//地图位置刷新
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    /*
     当前位置的蓝点是大头针视图,MKUserLocation是大头针模型,视图是根据模型展示的
     MKUserLocation : 被称作“大头针模型”,本质是一个数据模型,只不过此模型遵循了大头针要遵循的协议(MKAnnotation)
     location:  用户当前所在位置信息(CLLocation对象)
     title:     大头针标注要显示的标题(NSString对象)
     subtitle:  大头针标注要显示的子标题(NSString对象)
     */
    userLocation.title = @"当前位置";
    userLocation.subtitle = [NSString stringWithFormat:@"设备朝向 %@",userLocation.heading];
    self.currentCoordinate = userLocation.coordinate;
    //第一种方法:设置蓝点在地图中心,设置这个以后就没有朝向了,并且只能手动放大
    //    [mapView setCenterCoordinate:userLocation.coordinate animated:YES];
    //第二种方法:设置蓝点在地图中心,设置这个以后就没有朝向了,会自动放大
    /*
     MKCoordinateSpan 跨度解释:
     latitudeDelta:纬度跨度,因为南北纬各90度,所以此值的范围是(0---180);此值表示,整个地图视图宽度,显示多大跨度
     longitudeDelta:经度跨度,因为东西经各180度,所以此值范围是(0---360):此值表示,整个地图视图高度,显示多大跨度
     注意:地图视图显示,不会更改地图的比例,会以地图视图高度或宽度较小的那个为基准,按比例调整
     */
    //设置经纬度跨度,越小地图详细
    MKCoordinateSpan  span = MKCoordinateSpanMake(0.01, 0.01);
        //    设置经纬度区域
    MKCoordinateRegion region = MKCoordinateRegionMake(userLocation.coordinate, span);
        //    设置地图显示区域
    [mapView setRegion:region animated:YES];
    
}

2,地图区域改变

//地图区域改变调用,在这个方法里,手动放大地图区域,找到最适合的经纬度跨度
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    NSLog(@"纬度%f,经度%f",mapView.region.span.latitudeDelta,mapView.region.span.longitudeDelta);
}

4,大头针Annotation

4.1,核心概念

大头针是地图上一个一个标注的点,实质是一个又一个的大头针数据模型,mapView会自动根据拥有的模型来显示大头针视图,添加大头针,设置大头针,删除大头针,实质都是对大头针数据模型的操作。操作以后刷新maoView。

4.2.1 创建自定义的大头针,遵循MKAnnotation协议

原因:系统没有自带的Annotation基础模型,所以需要自定义NSObject类,并且遵循MKAnnotation协议,协议里是一些属性,直接拿过来后去掉只读属性,就有了一个自定义的Annotation数据模型。

4.2.2根据经纬度坐标添加大头针

// 根据经纬度坐标添加大头针
- (void)addAnnotationWithCoordinate:(CLLocationCoordinate2D)coordinate
{
    
    //    实际操作中使用地址编码创建CLLocationCoordinate2D指定大头针的位置
    CustomAnnotation *annotation = [[CustomAnnotation alloc] init];
    self.currentAnnotation = annotation;
    self.currentAnnotation.coordinate = coordinate;
    [self.customMapView addAnnotation:self.currentAnnotation];
    
}

4.2.3将点击的坐标转换为经纬度添加大头针


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//    [self addAnnotation];

    // 获取当前触摸点在地图上的坐标
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:self.customMapView];
    // 将坐标转换为经纬度
    CLLocationCoordinate2D center = [self.customMapView convertPoint:touchPoint toCoordinateFromView:self.customMapView];

    [self addAnnotationWithCoordinate:center];
}

4,2.4删除所有大头针

//    删除所有的的大头针
    [self.customMapView removeAnnotations:self.customMapView.annotations];

同理也可以删除某个大头针

4,2.5反地理编码得到点击处的地名

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 获取当前触摸点在地图上的坐标
    UITouch *touch = [touches anyObject];
    //点击的坐标
    CGPoint touchPoint = [touch locationInView:self.customMapView];
    // 将坐标转换为经纬度
    CLLocationCoordinate2D center = [self.customMapView convertPoint:touchPoint toCoordinateFromView:self.customMapView];
    CustomAnnotation * annotation = [[CustomAnnotation alloc]init];
    self.currentAnnotation = annotation;
    // 创建CLLocation对象
    CLLocation *location = [[CLLocation alloc] initWithLatitude:center.latitude longitude:center.longitude];
    // 根据CLLocation对象进行反地理编码
    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
        
        if (error) {
            NSLog(@"%@",error);
        }
        // 包含区,街道等信息的地标对象
        CLPlacemark *placemark = [placemarks firstObject];
        // 城市名称
        //        NSString *city = placemark.locality;
        // 街道名称
        //        NSString *street = placemark.thoroughfare;
        // 全称
        self.currentAnnotation.title = placemark.name;
        self.currentAnnotation.subtitle = placemark.country;
    }];
    
    [self addAnnotationWithCoordinate:center];
}

4.2.6自定义大头针

#pragma mark 自定义大头针
// 当添加大头针数据模型时,会调用此方法,获取对应的大头针视图。如果返回nil,则默认使用系统自带的大头针视图。
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(CustomAnnotation *)annotation{
//    循环使用
    static NSString *pinID = @"pinID";
    MKAnnotationView *customPinView = [mapView dequeueReusableAnnotationViewWithIdentifier:pinID];
    if (!customPinView) {
        customPinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinID];
    }
    
//    二次赋值,保证是真正的值,而不是循环复用的值
//    customPinView.annotation = annotation;
    NSString *imageName = nil;
//    保证一定加载
    if(self.currentAnnotation)
    {
        switch (annotation.AT) {
            case AnnotationTypeMovie:
                imageName = @"category_5";
                break;
            case AnnotationTypeHotel:
                imageName = @"category_3";
                break;
                
            default:
                break;
        }
    }
    
    customPinView.image = [UIImage imageNamed:@"category_5"];
    customPinView.canShowCallout = YES;
    // 设置标注左侧视图
    UIImageView *leftIV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
    leftIV.image = [UIImage imageNamed:@"huba.jpeg"];
    customPinView.leftCalloutAccessoryView = leftIV;

    // 设置标注右侧视图
    UIImageView *rightIV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
    rightIV.image = [UIImage imageNamed:@"eason.jpg"];
    customPinView.rightCalloutAccessoryView = rightIV;

    // 设置标注详情视图(iOS9.0)
    customPinView.detailCalloutAccessoryView = [[UISwitch alloc] init];
    return customPinView;
}

注意

1,加载地图相当占内存,并且内存不会自动下降,所以如果不是必要,尽量禁止地图的缩放和拖动,只给用户看当前位置就行了。

github地址https://github.com/CDLOG/mapKitDemo

上一篇下一篇

猜你喜欢

热点阅读