Cowboy Tech

MapKit地图应用基础

MapKit基础讲解

Map Kit(地图套件)提供了一个接口,可以将地图直接嵌入到自己的视图中。通过Map Kit框架,可以在iOS应用程序中显示地图以及当前位置。通过属性的设定,可以轻松实现位置显示、添加地图注释,通过给定信息查找确定地标信息等相关功能。

  1. MKMapView:提供了一个可嵌入应用的地图界面。
  2. MKCoordinateRegin:设置地图显示区域。
  3. MKPointAnnotation:提供了在指定点添加注释的功能,不能自定义该类。
  4. MKPinAnnotation:通过此类可以对地图标注进行配置。
  5. MKAnnotationView:通过此类实现自定义地图标注功能。

创建地图应用

添加MKMapView到视图

MKMapView * mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:mapView];

MKMapView相关属性

[mapView setDelegate:self];
[mapView setMapType:MKMapTypeStandard]; //有卫星,标准地图等
[mapView setZoomEnabled:YES];  //设置地图缩放
[mapView setScrollEnabled:YES]; //设置地图移动
[mapView setRotateEnabled:YES]; //设置地图旋转

地图的显示区域

//Method.1 -- 通过跨度来设置地图的显示区域
//MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(-37.855339, 145.153377), MKCoordinateSpanMake(0.1, 0.1));

//Method.2 -- 通过距离来设置地图显示区域
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(-37.855339, 145.153377),100 ,100);

[mapView setRegion:[mapView regionThatFits:region]];

添加地图标注

设置地点坐标

//Method.1
CLLocationCoordinate2D coordinate2D = CLLocationCoordinate2DMake(39.936846 , 116.503729);

//Method.2
CLLocationCoordinate2D coordinate2D;
coordinate2D.latitude = 39.936846;
coordinate2D.longitude = 116.503729;

指定坐标点添加标注

MKPointAnnotation * pointAnntation1 = [[MKPointAnnotation alloc] init];
[pointAnntation1 setTitle:@"当前位置"];
[pointAnntation1 setSubtitle:@"位置说明"];
[pointAnntation1 setCoordinate:coordinate2D];
[mapView addAnnotation:pointAnntation1];

添加多个标注

//标注一
MKPointAnnotation * pointAnntation1 = [[MKPointAnnotation alloc] init];
[pointAnntation1 setTitle:@"当前位置"];
[pointAnntation1 setSubtitle:@"位置说明"];
[pointAnntation1 setCoordinate:coordinate2D];

//标注二
MKPointAnnotation * pointAnntation2 = [[MKPointAnnotation alloc] init];
[pointAnntation2 setTitle:@"当前位置"];
[pointAnntation2 setSubtitle:@"位置说明"];
[pointAnntation2 setCoordinate:coordinate2d];

NSArray * arrAnnitations = @[pointAnntation1,pointAnntation2];
[mapView addAnnotations:arrAnnitations];

地图启动时显示标注气泡

[mapView selectAnnotation:pointAnntation1 animated:YES];

设置标注样式

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{

static NSString * pinIdentifier = @"pin";

MKPinAnnotationView * pintAnntation = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];

if(!pintAnntation){

        pintAnntation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
        [pintAnntation setPinColor:MKPinAnnotationColorPurple];
        [pintAnntation setAnimatesDrop:YES];
        [pintAnntation setCanShowCallout:YES];
}

return pintAnntation;

自定义标注视图

  1. 创建annotation object,并实现MKAnnotation协议
  2. 创建自定义标注视图,继承自MKAnnotationView

ViewController

- (void)viewDidLoad {
...............
CLLocationCoordinate2D coordinate2D = CLLocationCoordinate2DMake(39.936846, 116.503729);
CustomAnnotation * customAnnotation = [[CustomAnnotation alloc] initWithCoordinate2D:coordinate2D];
[customAnnotation setTitle:@"我的位置"];
[customAnnotation setSubTitle:@"具体说明"];
[mapView addAnnotation:customAnnotation];    
}


- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString * customIdentifier = @"customView";

CustomAnnotationView * customAnnotationView = (CustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:customIdentifier];
if(!customAnnotationView){
    customAnnotationView = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:customIdentifier];
    [customAnnotationView setImage:[UIImage imageNamed:@"an"]];
    }
    return customAnnotationView;    
}

CustomAnnotation

@interface CustomAnnotation : NSObject<MKAnnotation>{
CLLocationCoordinate2D coord;
}

@property (nonatomic, readonly) CLLocationCoordinate2D coord;

@property (nonatomic, copy) NSString * title;
@property (nonatomic, copy) NSString * subTitle;

- (instancetype)initWithCoordinate2D:(CLLocationCoordinate2D)coordinate2D;

@end

@implementation CustomAnnotation
@synthesize coord;
@synthesize title,subTitle;

- (instancetype)initWithCoordinate2D:(CLLocationCoordinate2D)coordinate2D{
self = [super init];
if(self){
    coord = coordinate2D;
}

return self;
}

- (CLLocationCoordinate2D)coordinate{
return coord;
}

- (NSString *)title{
return title;
}

- (NSString *)subtitle{
return subTitle;
}
@end

CustomAnnotationView

@interface CustomAnnotationView : MKAnnotationView

@end

@interface CustomAnnotationView()

@property (nonatomic, strong) CustomAnnotation * customAnnotation;
@property (nonatomic, strong) UIView *infoView;

@end

@implementation CustomAnnotationView

- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if(self){
    self.customAnnotation = annotation;
}

return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
[super setSelected:selected animated:animated];
if(selected){
    self.infoView = [[UIView alloc] initWithFrame:CGRectMake(-(150-50)/2, -30, 150, 30)];
    [_infoView.layer setBorderColor:[UIColor blackColor].CGColor];
    [_infoView.layer setBorderWidth:1.f];
    [_infoView.layer setCornerRadius:5.f];
    [self.infoView setBackgroundColor:[UIColor whiteColor]];
    [self addSubview:self.infoView];

    UILabel * label = [[UILabel alloc] initWithFrame:_infoView.bounds];
    [label setFont:[UIFont systemFontOfSize:12]];
    [label setTextAlignment:NSTextAlignmentCenter];
    [label setText:[NSString stringWithFormat:@"%f %f",_customAnnotation.coordinate.latitude,_customAnnotation.coordinate.longitude]];
    [_infoView addSubview:label];

    CGFloat scale = 0.001f;

    [_infoView setTransform:CGAffineTransformMake(scale, 0, 0, scale, 0, 0)];
    [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        CGFloat scale = 1.1f;
        [_infoView setTransform:CGAffineTransformMake(scale, 0, 0, scale, 0, 2)];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            CGFloat scale = 0.9;
            [_infoView setTransform:CGAffineTransformMake(scale, 0, 0, scale, 0, -2)];
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.075 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                CGFloat scale = 1.0f;
                [_infoView setTransform:CGAffineTransformMake(scale, 0, 0, scale, 0, 0)];
            } completion:^(BOOL finished) {}];
        }];
    }];


}else{
    [UIView animateWithDuration:0.2 animations:^{
        [_infoView setAlpha:0.1];
    } completion:^(BOOL finished) {
        [_infoView removeFromSuperview];
    }];
}
}

选中标注时执行

MKAnnotationView

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{


}

MKMapView代理方法讲解

- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{
    //地图将要载入执行
}

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView{
    //地图载入完成以后执行
}

- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{
    //地图载入失败执行
    NSLog(@"error:%@",[error description]);
}

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated{
    //地图显示区域将要发生改变时执行
        UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"地图位置将要改变" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
        [alertView show];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    //地图显示区域改变以后执行
            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"地图位置已经改变" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [alertView show];

}

//添加标注时调用
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{

}

//标注被选中时执行此方法
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{

}

//标注失去焦点时执行
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{

}

//添加左右配件控件时才会调用
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {

}