概述
API
MKMapView
常用属性 地图配型:mapType MKMapTypeStandard :普通地图(左图) MKMapTypeSatellite :卫星云图 (中图) MKMapTypeHybrid :混合模式(普通地图覆盖于卫星云图之上 ) MKMapTypeSatelliteFlyover: 3D立体卫星 (iOS9.0) MKMapTypeHybridFlyover: 3D立体混合 (iOS9.0) 操作项 是否可缩放 zoomEnabled 是否可滚动 scrollEnabled 是否可旋转 rotateEnabled 显示项 是否显示指南针 showsCompass (iOS9.0) 是否显示比例尺 showsScale (iOS9.0) 是否显示交通 showsTraffic (iOS9.0) 是否显示建筑 showsBuildings 跟踪显示用户的位置(ios8-地图不会自动滚到用户所在的位置,ios8+地图会自动放大到合适比例,并显示出用户位置) MKUserTrackingModeNone :不跟踪用户的位置 MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置 MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转 设置地图显示的区域和位置 设置地图的中心点位置 @property (nonatomic) CLLocationCoordinate2D centerCoordinate; -(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated; 设置地图的显示区域 @property (nonatomic) MKCoordinateRegion region; -(void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
mapView = [[MKMapView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:mapView]; mapView.mapType = MKMapTypeStandard; mapView.showsBuildings = false; mapView.showsScale = true; mapView.showsTraffic = false; mapView.showsCompass = false; mapView.zoomEnabled = true;//缩放 mapView.scrollEnabled = true;//滚动 mapView.rotateEnabled = true;//旋转 mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;//是否显示用户的位置 mapView.delegate = self;
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation; 一个位置更改默认只会调用一次,不断监测用户的当前位置 每次调用,都会把用户的最新位置(userLocation参数)传进来 -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated; 地图的显示区域即将发生改变的时候调用 -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated; 地图的显示区域已经发生改变的时候调用
大头针
anno = [[MKPointAnnotation alloc] init]; anno.title = @"我是一个大头针"; anno.subtitle = @"我有一个小弟叫小头"; anno.coordinate = CLLocationCoordinate2DMake(22.568694, 113.87023); [mapView addAnnotation:anno];
1.自定义大头针可以继承大头针类
2.添加多个大头针可以使用Array
一.自定大头针模型MKAnnotation
二.自定义大头针控件MKAnnotationView
①MKAnnotationView 类似cell
②MKAnnotation 类似表视图里面的model
③- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 类似初始化cell的地方
④如果只添加了annotation 会自动添加一个大头针视图 pinAnnotationView
②MKAnnotation 类似表视图里面的model
③- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 类似初始化cell的地方
④如果只添加了annotation 会自动添加一个大头针视图 pinAnnotationView
1.点击添加大头针
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //我们只需要添加大头针模型,剩下的就由系统帮我们做好 //1.创建大头针模型 //MKAnnotation *an = [[MKAnnotation alloc] init]; //这地方需要注意 HMAnnotation *annotation = [[HMAnnotation alloc] init]; //2.获取在屏幕上的点击位置 UITouch *touch = [touches anyObject]; //2.1 获取坐标点 CGPoint point = [touch locationInView:self.mapView]; //2.2 将UIKit的坐标点,转成经纬度 CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView]; //3.设置大头针相关属性(设置坐标) annotation.coordinate = coordinate; //3.1 设置大头针的标题 annotation.title = @"夜黑风高我来也"; annotation.subtitle = @"西门吹雪战队"; //4.添加大头针模型 [self.mapView addAnnotation:annotation]; }
2.从服务器添加大头针
for (int i = 0; i < _fDataArray.count; i++) { ResModel *model = _fDataArray[i]; CLLocationCoordinate2D center = CLLocationCoordinate2DMake([[model.loc objectForKey:@"lat"] doubleValue],[[model.loc objectForKey:@"lon"] doubleValue]); MKPointAnnotation *pinAnnotation = [[MKPointAnnotation alloc] init]; pinAnnotation.coordinate = center; pinAnnotation.title = model.name; [_mapView addAnnotation:pinAnnotation]; }
3.自定义大头针
#import <MapKit/MapKit.h> @interface myAnnotationView : MKAnnotationView @property (nonatomic,strong) UILabel *label; @end
@implementation myAnnotationView - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier{ self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; if (self) { // 在大头针旁边(上下左右)加一个label self.label = [[UILabel alloc]initWithFrame:CGRectMake(-5, -20, 60, 50)]; self.label.textColor = [UIColor blackColor]; self.label.textAlignment = NSTextAlignmentCenter; self.label.font = [UIFont systemFontOfSize:10]; self.label.lineBreakMode = 0; self.label.numberOfLines = 0; [self addSubview:self.label]; } return self; } @end
4.大头针的重用机制
// 大头针视图的重用,大头针也存在着重用的机制,方便优化内存 // 每次添加大头针都会调用此方法 可以设置大头针的样式 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{ // 判断大头针位置是否在原点,如果是则不加大头针或者添加属于自己特殊图标 if ([annotation isKindOfClass:[MKUserLocation class]]) { return nil; } //1.定义一个可重用标识符 static NSString *reuseIdentifier = @"mapView"; MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier]; if (annotationView == nil) { annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; } //设置可重用标识符的相关属性 // 显示标题和副标题 annotationView.canShowCallout = YES; // 设置图片(用户头像,或者商品/超市/汽车/单车等等图片) annotationView.image = [UIImage imageNamed:@"appStore"]; //须导入#import "UIImageView+WebCache.h"头文件 // [annotationView.image sd_setImageWithURL:[NSURL URLWithString:[dict valueForKey:@"icon"]] placeholderImage:[UIImage imageNamed:@"默认图片"]]; return annotationView; }
5.动画的效果
// 已经添加了大头针模型,还没有完全渲染出来之前(mapView的代理) - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray<MKAnnotationView *> *)views{ for (MKAnnotationView *annotationView in views) { //目标位置 CGRect targetRect = annotationView.frame; //先让其在最顶上 annotationView.frame = CGRectMake(targetRect.origin.x, 0, targetRect.size.width, targetRect.size.height); //最后通过动画展示到最终的目标地方 [UIView animateWithDuration:0.3 animations:^{ annotationView.frame = targetRect; }]; } }
MKMapView常用功能
1. 地图返回到用户的位置
方式1,设置用户的跟踪模式
方式2,设置用户所在的区域(确定中心点,确定区域大小)
//方式一 self.mapView.userTrackingMode = MKUserTrackingModeFollow; [self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES]; //方式二 MKCoordinateRegion region = MKCoordinateRegionMake(self.mapView.userLocation.location.coordinate, self.mapView.region.span); [self.mapView setRegion:region animated:YES];
2.放大视图
/设置其区域 CLLocationDegrees latitudeDelta = self.mapView.region.span.latitudeDelta * 0.5; CLLocationDegrees longitudeDelta = self.mapView.region.span.longitudeDelta * 0.5; MKCoordinateSpan changeSpan = MKCoordinateSpanMake(latitudeDelta, longitudeDelta); //设置变大 [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.region.center, changeSpan) animated:YES];
2.缩小视图
//设置其区域 //只改变区域大小,不改变中心位置 CLLocationDegrees latitudeDelta = self.mapView.region.span.latitudeDelta * 1.5; CLLocationDegrees longitudeDelta = self.mapView.region.span.longitudeDelta * 1.5; MKCoordinateSpan changeSpan = MKCoordinateSpanMake(latitudeDelta, longitudeDelta); //设置变大 [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.region.center, changeSpan) animated:YES];
3.计算两点的位置
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:39.6 longitude:116.2]; CLLocation *location2 = [[CLLocation alloc] initWithLatitude:28.5 longitude:118.3]; float distance = [location1 distanceFromLocation:location2]; NSLog(@"%f km",distance / 1000);
MKMapView导航
CLLocationCoordinate2D coords1 = {22.56912,113.870033}; CLLocationCoordinate2D coords2 = {22.570555,113.871039}; MKMapItem *currentLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coords1 addressDictionary:nil]]; MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coords2 addressDictionary:nil]]; NSArray *items = [NSArray arrayWithObjects:currentLocation, toLocation, nil]; NSDictionary *options = @{ MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsMapTypeKey: [NSNumber numberWithInteger:MKMapTypeStandard], MKLaunchOptionsShowsTrafficKey:@YES }; //打开苹果自身地图应用,并呈现特定的item [MKMapItem openMapsWithItems:items launchOptions:options];