(八十)MapKit放置系统默认大头针和自定义大头针

来源:互联网 发布:域名虚拟主机哪家好 编辑:程序博客网 时间:2024/05/22 12:31

有关MapView的显示和定位在上一节已经说明,这一节说明如何在地图上放置大头针,以及设置点击大头针的视图。

【系统默认大头针】

mapView上放置大头针的方法是调用其addAnnotation:方法,需要注意的是,传入的是模型而不是大头针视图。

- (void)addAnnotation:(id <MKAnnotation>)annotation;
通过这个方法,我们可以清楚的看到,annotation模型需要遵循MKAnnotation协议,我们打开这个协议,可以看到如下的内容:

@protocol MKAnnotation <NSObject>// Center latitude and longitude of the annotation view.// The implementation of this property must be KVO compliant.@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;@optional// Title and subtitle for use by selection UI.@property (nonatomic, readonly, copy) NSString *title;@property (nonatomic, readonly, copy) NSString *subtitle;// Called as a result of dragging an annotation view.- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate NS_AVAILABLE(10_9, 4_0);@end
因此我们应当定义一个模型,按照协议定义这些属性,其中coordinate是必须定义的,因为大头针必须有位置。

模型类遵循MKAnnocation协议,命名为MyAnnotation,如下:

#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
#import "MyAnnotation.h"@implementation MyAnnotation@end


然后就可以通过定义模型,调用addAnnotation:方法添加一枚大头针,例如我们通过Button,随机添加一枚大头针:

- (IBAction)addPin:(id)sender {        MyAnnotation *anno = [[MyAnnotation alloc] init];    anno.title = @"title";    anno.subtitle = @"subtitle";    CLLocationDegrees latitude = 36.821119 + arc4random_uniform(20);    CLLocationDegrees longtitude = 116.750112 + arc4random_uniform(20);    anno.coordinate = CLLocationCoordinate2DMake(latitude, longtitude);        [self.mapView addAnnotation:anno];}

其中的title和subtitle是点击大头针时显示的气泡上的标题和副标题。

大头针的显示原理和tableView显示cell是类似的,一旦调用addAnnotation:方法,就会调用mapView:viewForAnnotationView:方法,这个方法中应当从缓存池取出一个大头针视图,或者如果缓存池中没有新建一个大头针视图,然后返回。

与tableView的区别是,如果直接返回nil,则会按照系统的样式返回大头针。

需要注意的是,如果不返回nil,要对不同类型的大头针进行处理,不要忘了用户的位置指示圆点也属于一种大头针,如果只是单单的设置大头针,连用户位置也会是一颗针而不是圆点


判断方法很简单,因为用户位置大头针由系统创建,因此传入的模型肯定不是我们自己的模型MyAnnotation,只要判断传入的模型是不是这个类,如果不是,则返回nil,代表按照系统默认样式,创建圆点。


要创建大头针,使用的是MKPinAnnotationView,如果使用MKAnnotationView,是不带图片的,无法直接显示。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{        static NSString *ID = @"anno";    // 如果返回nil,系统会按照默认方式显示,如果自定义,是无法直接显示的,并且点击大头针之后不会显示标题,需要自己手动设置显示    // 如果想要直接显示,应该调用MKPinAnnotationView    MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];        if (annoView == nil) {        annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];        // 大头针属性        annoView.animatesDrop = YES; // 设置大头针坠落的动画        annoView.canShowCallout = YES; // 设置点击大头针是否显示气泡        annoView.calloutOffset = CGPointMake(0, 0); // 设置大头针气泡的偏移        // 设置大头针气泡的左右视图、可以为任意UIView        annoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];        annoView.rightCalloutAccessoryView = [[UISwitch alloc] init];        [annoView setPinColor:MKPinAnnotationColorPurple]; // 设置大头针颜色    }        // 设置大头针的图片,如果是直接创建MKPin,则无效。    //annoView.image = [UIImage imageNamed:@"pin"];        annoView.annotation = annotation;        // 如果是用户位置,应当显示默认的圆点而不是大头针,因此应当判断是否是MyAnnotation    if(![annoView.annotation isKindOfClass:[MyAnnotation class]]){        return nil;    }        return annoView;    }

【自定义大头针】

自定义大头针需要使用MKAnnotationView,自己指定image,没有坠落动画,其他没有区别。

 (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{        static NSString *ID = @"anno";    // 如果返回nil,系统会按照默认方式显示,如果自定义,是无法直接显示的,并且点击大头针之后不会显示标题,需要自己手动设置显示    // 如果想要直接显示,应该调用MKPinAnnotationView    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];        if (annoView == nil) {        annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];        // 大头针属性        //annoView.animatesDrop = YES; // MKPinAnnotaionView才有效,设置大头针坠落的动画        annoView.canShowCallout = YES; // 设置点击大头针是否显示气泡        annoView.calloutOffset = CGPointMake(0, 0); // 设置大头针气泡的偏移        // 设置大头针气泡的左右视图、可以为任意UIView        annoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];        annoView.rightCalloutAccessoryView = [[UISwitch alloc] init];        //[annoView setPinColor:MKPinAnnotationColorPurple]; // MKPinAnnotaionView才有效,设置大头针的颜色    }        // 设置大头针的图片    annoView.image = [UIImage imageNamed:@"pin"];        annoView.annotation = annotation;        // 如果是用户位置,应当显示默认的圆点而不是大头针,因此应当判断是否是MyAnnotation    if(![annoView.annotation isKindOfClass:[MyAnnotation class]]){        return nil;    }        return annoView;    }

【MVC封装annotationView的注意点】

annotation要传入模型,在重写的set方法里,注意调用父类的set方法,先设置公共属性,再设置自己所特有的。

有一个细节,默认set方法的传入模型是id<MKAnnotaion>类型,在使用时还需要强转类型,为了方便,我们直接把类型改为MyAnnotation,因为OC在调用方法时发送的消息只包括方法名和冒号、描述,因此类型不属于方法名的一部分,可以修改。

- (void)setAnnotation:(MyAnnotation *)annotation{   [super setAnnotation:annotation];   // 设置特有的属性,例如图片、左右视图等。}


0 0
原创粉丝点击