苹果自带的地图是高德地图
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,加载地图相当占内存,并且内存不会自动下降,所以如果不是必要,尽量禁止地图的缩放和拖动,只给用户看当前位置就行了。
网友评论