自定义大头针

添加自定义大头针,使用系统大头针View

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnotation.h"

@interface ViewController () <MKMapViewDelegate>

// 显示地图的View
@property (weak, nonatomic) IBOutlet MKMapView *mapView;


@property (nonatomic,strong) CLLocationManager *mgr;

/**
 *  点击之后添加两个大头针
 */
- (IBAction)addAnnotation;



@end

@implementation ViewController

- (CLLocationManager *)mgr{
    if (!_mgr) {
        _mgr = [[CLLocationManager alloc] init];
        
        [_mgr requestAlwaysAuthorization];
//        [_mgr requestWhenInUseAuthorization];
//         并在Info.plist添加2个属性
//        从iOS 8开始,用户定位分两种情况
//        总是使用用户位置:NSLocationAlwaysUsageDescription
//        使用应用时定位:NSLocationWhenInUseDescription

    }
    return _mgr;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.mgr;
    
    // 1.设置代理
    self.mapView.delegate = self;
    
    // 2.跟踪用户的位置
    self.mapView.userTrackingMode = MKUserTrackingModeFollow;
}

/**
 *  定位到用户的位置会调用该方法
 *
 *  @param userLocation 大头针模型对象
 */
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    // 设置用户的位置为地图的中心点
    [mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}

/**
 *  在地图上添加一个大头针就会执行该方法
 *
 *  @param annotation 大头针模型对象
 *
 *  @return 大头针的View(返回nil表示默认使用系统, 默认MKAnnotationView是不可见)
 */
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    // 1.如果是用户位置的大头针,直接返回nil,使用系统的
    if ([annotation isKindOfClass:[MKUserLocation class]]) return nil;
    
    // 2.创建标识
    static NSString *ID = @"annoView";
    // 3.从缓冲池中取出大头针的View
    MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    // 4.如果为nil,则创建
    if (annoView == nil) {
        annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];
        
        // 1.设置标题和子标题可以呼出
        annoView.canShowCallout = YES;
        
        // 2.设置大头针的颜色
        annoView.pinColor = MKPinAnnotationColorPurple;
        
        // 3.掉落效果
        annoView.animatesDrop = YES;
    }
    
    
    // 5.设置大头针的大头针模型,也可以不对其进行设置,系统会自动进行设置
//    annoView.annotation = annotation;
    
    return annoView;
}

- (IBAction)addAnnotation {
    MyAnnotation *anno1 = [[MyAnnotation alloc] init];
    anno1.coordinate = CLLocationCoordinate2DMake(40.06, 116.39);
    anno1.title = @"北京市";
    anno1.subtitle = @"中国北京市昌平区";
    [self.mapView addAnnotation:anno1];
    
    MyAnnotation *anno2 = [[MyAnnotation alloc] init];
    anno2.coordinate = CLLocationCoordinate2DMake(30.23, 120.23);
    anno2.title = @"杭州市";
    anno2.subtitle = @"浙江省杭州市萧山区";
    [self.mapView addAnnotation:anno2];
}
@end

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MyAnnotation : NSObject <MKAnnotation>

@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;

@end

自定义大头针,大头针View

自定义大头针显示View

#import <MapKit/MapKit.h>

@interface MyAnnotationView : MKAnnotationView

+ (instancetype)myAnnoViewWithMapView:(MKMapView *)mapView;

@end

#import "MyAnnotationView.h"
#import "MyAnnotation.h"

@implementation MyAnnotationView

+ (instancetype)myAnnoViewWithMapView:(MKMapView *)mapView
{
    // 2.添加自己的大头针的View
    static NSString *ID = @"myAnnoView";
    MyAnnotationView *myAnnoView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    if (myAnnoView == nil) {
        myAnnoView = [[MyAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];
        
        // 1.设置标题和子标题可以呼出
        myAnnoView.canShowCallout = YES;
        
        // 2.在左右两侧放一个View
        myAnnoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
        myAnnoView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    }
    
    return myAnnoView;
}


- (void)setAnnotation:(MyAnnotation *)annotation
{
    self.image = [UIImage imageNamed:annotation.icon];
    
    [super setAnnotation:annotation];
}

@end

自定义大头针模型

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MyAnnotation : NSObject <MKAnnotation>

@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@property (nonatomic, copy) NSString *icon;

@end

#import "MyAnnotation.h"

@implementation MyAnnotation

@end

控制器:

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnotation.h"
#import "MyAnnotationView.h"

@interface ViewController () <MKMapViewDelegate>

// 显示地图的View
@property (weak, nonatomic) IBOutlet MKMapView *mapView;

@property (nonatomic,strong) CLLocationManager *mgr;

/**
 *  点击之后添加两个大头针
 */
- (IBAction)addAnnotation;

@end

@implementation ViewController

- (CLLocationManager *)mgr{
    if (!_mgr) {
        _mgr = [[CLLocationManager alloc] init];
        
        [_mgr requestAlwaysAuthorization];
        //        [_mgr requestWhenInUseAuthorization];
        //         并在Info.plist添加2个属性
        //        从iOS 8开始,用户定位分两种情况
        //        总是使用用户位置:NSLocationAlwaysUsageDescription
        //        使用应用时定位:NSLocationWhenInUseDescription
        
    }
    return _mgr;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.设置代理
    self.mapView.delegate = self;
    
    // 2.跟踪用户的位置
    self.mapView.userTrackingMode = MKUserTrackingModeFollow;
}

/**
 *  定位到用户的位置会调用该方法
 *
 *  @param userLocation 大头针模型对象
 */
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    // 设置用户的位置为地图的中心点
    [mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}

/**
 *  在地图上添加一个大头针就会执行该方法
 *
 *  @param annotation 大头针模型对象
 *
 *  @return 大头针的View(返回nil表示默认使用系统, 默认MKAnnotationView是不可见)
 */

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    // 1.如果是用户位置的大头针,直接返回nil,使用系统的
    if ([annotation isKindOfClass:[MKUserLocation class]]) return nil;
    
    // 2.添加自己的大头针的View
    MyAnnotationView *myAnnoView = [MyAnnotationView myAnnoViewWithMapView:mapView];
    
    return myAnnoView;
}

/**
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    // 1.如果是用户位置的大头针,直接返回nil,使用系统的
    if ([annotation isKindOfClass:[MKUserLocation class]]) return nil;
    
    // 2.添加自己的大头针的View
    static NSString *ID = @"myAnnoView";
    MyAnnotationView *myAnnoView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    if (myAnnoView == nil) {
        myAnnoView = [[MyAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];
        
        // 设置图片
        // myAnnoView.image = [UIImage imageNamed:@"category_1"];
        // 1.设置标题和子标题可以呼出
        myAnnoView.canShowCallout = YES;
        
        // 2.在左右两侧放一个View
        myAnnoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
        myAnnoView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    }
    // 只需要设置大头针模型数据,无需手动把大头针View和大头针模型进行关联,系统会自动关联,也就是会调用view中setAnnotation方法进行设置
    MyAnnotation *anno = (MyAnnotation *)annotation;
    myAnnoView.image = [UIImage imageNamed:anno.icon];
    
    return myAnnoView;
}
 */

/**
 *  大头针的View已经被添加mapView会执行该方法
 *
 *  @param views   所有大头针的View都存放在该数组中
 */
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    // 对大头针动画执行掉落效果
    
    //MKModernUserLocationView
    for (MKAnnotationView *annoView in views) {
        // 如果是系统的大头针View直接返回
        if ([annoView.annotation isKindOfClass:[MKUserLocation class]]) return;
        
        // 取出大头针View的最终应该在位置
        CGRect endFrame = annoView.frame;
        
        // 给大头针重新设置一个位置
        annoView.frame = CGRectMake(endFrame.origin.x, 0, endFrame.size.width, endFrame.size.height);
        
        // 执行动画
        [UIView animateWithDuration:0.5 animations:^{
            annoView.frame = endFrame;
        }];
    }
}

- (IBAction)addAnnotation {
    MyAnnotation *anno1 = [[MyAnnotation alloc] init];
    anno1.coordinate = CLLocationCoordinate2DMake(40.06, 116.39);
    anno1.title = @"北京市";
    anno1.subtitle = @"中国北京市昌平区";
    anno1.icon = @"category_1";
    [self.mapView addAnnotation:anno1];
    
    MyAnnotation *anno2 = [[MyAnnotation alloc] init];
    anno2.coordinate = CLLocationCoordinate2DMake(30.23, 120.23);
    anno2.title = @"杭州市";
    anno2.subtitle = @"浙江省杭州市萧山区";
    anno2.icon = @"category_2";
    [self.mapView addAnnotation:anno2];
}
@end
原文地址:https://www.cnblogs.com/HJiang/p/4344581.html