iOS:MKMapView上画标记图标

本文详细介绍了如何在iOS的MKMapView上创建自定义地图标记,包括实现自定义MKAnnotation和MKAnnotationView,以及在点击标记时弹出自定义对话框的完整步骤。内容涵盖创建自定义类、实现MKAnnotation协议、重写mapView-viewForAnnotation方法以及监听标记点击事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值