说明:
MKMapView是地图控件,支持在地图上画各种标记图标。
一、创建自定义地图标记:
1.创建普通类,继承NSObject,实现MKAnnotation:
PopAnotation.h:
// 地图标记
// PopAnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface PopAnotation : NSObject <MKAnnotation>
//经纬度值
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
//标题
@property (nonatomic, copy) NSString *title;
//描述
@property (nonatomic, copy) NSString *desc;
//图标
@property (nonatomic, copy) UIImage *image;
@end
PopAnotation.m:
// 地图标记
// PopAnotation.m
#import "PopAnotation.h"
@implementation PopAnotation
@end
2.根据经纬度值增加自定义MKAnnotation,需要手动调用:
/*
自定义方法:根据经纬度值增加自定义MKAnnotation标记图标
*/
- (void)addItemAnotation2{
//创建有经纬度值的标记图标
PopAnotation *popA = [[PopAnotation alloc] init];
popA.title = @"pop标题";
popA.desc = @"pop描述";
popA.image = [UIImage imageNamed:@"pop1"];
//根据经纬度创建点
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(116.4, 39.9);
popA.coordinate = coordinate;
//将标记图标加入mapView中
[self.mapView addAnnotation:popA];
}
4.重写mapView-viewForAnnotation方法,创建自定义MKAnnotation,替换系统MKAnnotationView中的annotation:
/*
MKMapViewDelegate方法:改变地图标记样式
*/
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
if([annotation isKindOfClass:[PopAnotation class]]){//地图标记MKAnnotation
//定义id值
static NSString *_id = @"popA";
//从缓存中取出单个MKAnnotationView
MKAnnotationView *popAV = [mapView dequeueReusableAnnotationViewWithIdentifier:_id];
if(popAV == nil){//缓存中为空时,根据id值创建新的MKAnnotationView
popAV = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:_id];
}
//将MKAnnotation引用赋值给MKAnnotationView的annotation
popAV.annotation = annotation;
//annotation本身就是自定义的MKAnnotation
PopAnotation *popA = annotation;
//设置标记图标
popAV.image = popA.image;
//这里返回系统自带的MKAnnotationView
return popAV;
}
return nil;
}
二、创建点击标记时的弹出框:
1.创建自定义MKAnnotation,继承NSObject,实现MKAnnotation:
DialogAnnotation.h:
// 弹出框
// DialogAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface DialogAnnotation : NSObject <MKAnnotation>
//经纬度值
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@end
DialogAnnotation.m:
// 弹出框
// DialogAnnotation.m
#import "DialogAnnotation.h"
@implementation DialogAnnotation
@end
2.创建自定义MKAnnotationView类:
DialogAnnotationView.h:
// 弹出框View
// DialogAnnotationView.h
#import <MapKit/MapKit.h>
#import "DialogView.h"
@interface DialogAnnotationView : MKAnnotationView
@end
DialogAnnotationView.m:
// 弹出框View
// DialogAnnotationView.m
#import "DialogAnnotationView.h"
@implementation DialogAnnotationView
/*
初始化
*/
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){
//创建xib所在的View
DialogView *childV = [DialogView createXib];
//设置xib所在的View的位置
CGRect frame = childV.frame;
frame.origin.y = 35;
childV.frame = frame;
//将xib所在的View加入到弹出框中
[self addSubview:childV];
//设置弹出框的位置与宽高
self.frame = CGRectMake(0, 0, childV.frame.size.width, childV.frame.size.height + 60);
}
return self;
}
@end
3.创建弹出框内部自定义View(xib实现):
(1)DialogView.h:
// 弹出框内部View
// DialogView.h
#import <UIKit/UIKit.h>
@interface DialogView : UIView
//加载xib的类方法(静态方法)
+ (instancetype) createXib;
@end
(2)DialogView.m:
// 弹出框内部View
// DialogView.m
#import "DialogView.h"
@implementation DialogView
/*
加载xib的类方法(静态方法)
*/
+ (instancetype)createXib{
//加载xib
return [[[NSBundle mainBundle] loadNibNamed:@"DialogView" owner:nil options:nil] lastObject];
}
@end
(3)创建xib,打开视图,拖入一个UIView,选中,将右侧Custom Class改为自定义UIView类DialogView,并拖入要显示的View。
4.重写mapView-viewForAnnotation方法,创建自定义MKAnnotation,返回自定义MKAnnotationView:
/*
MKMapViewDelegate方法:改变地图标记样式
*/
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
if([annotation isKindOfClass:[DialogAnnotation class]]){//弹出框MKAnnotation
//定义id值
static NSString *_id = @"dialogA";
//从缓存中取出单个DialogAnnotationView
DialogAnnotationView *dialogAV = (DialogAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:_id];
if(dialogAV == nil){//缓存中为空时,根据id值创建新的MKAnnotationView
dialogAV = [[DialogAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:_id];
}
//将MKAnnotation引用赋值给DialogAnnotationView的annotation
dialogAV.annotation = annotation;
//这里返回自定义的DialogAnnotationView
return dialogAV;
}
return nil;
}
三、在点击地图标记时,新增弹出框:
1.重写mapView-didSelectAnnotationView方法,监听标记点击事件:
/*
MKMapViewDelegate方法:选中某个标记图标时触发
*/
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
//获取点击的标记
PopAnotation *popA = view.annotation;
//创建弹出框
DialogAnnotation *dialogA = [[DialogAnnotation alloc] init];
dialogA.coordinate = popA.coordinate;
//添加弹出框
[mapView addAnnotation:dialogA];
NSLog(@"anotation : %@", popA);
}
四、其他一些方法:
1.根据点击位置增加自定义MKAnnotation:
/*
自定义方法:根据点击位置增加自定义MKAnnotation
*/
- (void)addItemAnotation:(UITapGestureRecognizer *)recognizer{
//获得点击位置xy坐标
CGPoint point = [recognizer locationInView:recognizer.view];
//将xy坐标转换为经纬度值
CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
//创建有经纬度值的标记图标
PopAnotation *popA = [[PopAnotation alloc] init];
popA.title = @"pop标题";
popA.desc = @"pop描述";
popA.image = [UIImage imageNamed:@"pop1"];
popA.coordinate = coordinate;
[self.mapView addAnnotation:popA];
// self.mapView addAnnotations:<#(nonnull NSArray<id<MKAnnotation>> *)#>;
//移除某个标记图标
// self.mapView removeAnnotation:<#(nonnull id<MKAnnotation>)#>;
//移除标记图标列表
// self.mapView removeAnnotations:<#(nonnull NSArray<id<MKAnnotation>> *)#>;
}
2.使用系统自带的标记:
/*
自定义方法:使用系统自带的标记
*/
- (MKAnnotationView *)getAnnotationView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
//定义id值
static NSString *_id = @"popItem";
//从缓存中取出单个MKAnnotationView
MKAnnotationView *annV = [mapView dequeueReusableAnnotationViewWithIdentifier:_id];
if(annV == nil){//缓存中为空时,根据id值创建新的MKAnnotationView
annV = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:_id];
//显示标题与描述
annV.canShowCallout = YES;
//设置标记图标间距
annV.calloutOffset = CGPointMake(5, 5);
//在描述右边加按钮
annV.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//在描述右边加按钮
annV.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
//采用这种标记类可以使用动画效果
// MKPinAnnotationView *annV2 = nil;
// annV2.animatesDrop = YES;
}
//将MKAnnotation引用赋值给MKAnnotationView的annotation
annV.annotation = annotation;
//annotation本身就是自定义的MKAnnotation
PopAnotation *popA = annotation;
//设置标记图标
annV.image = popA.image;
return annV;
}