自定义annotationView
最简单的用法
在viewForAnnotation方法中,建立一个MKAnnotationView对象,并修改其image属性为想要的图片。返回此对象。
自定义MKAnnotationView
建立一个类,继承于MKAnnotationView,设置它的self.image属性。
annotationView的位置
默认为View的中心,所以如果想让图片下方的箭头在坐标上,需要设置centerOffset属性:
self.centerOffset = CGPointMake(0, -20);
自定义calloutView
默认的calloutView
设置annotationView的canShowCallout属性为YES。点击annotation时候就会弹出calloutView。此calloutView会显示两个label,分别是annotation的title和subtitle。
可以简单定制此calloutView,通过设置annotationView的leftCalloutAccessoryView和rightCalloutAccessoryView为calloutView加上左边和右边的view。
(是否可以把title设置为nil,完全通过calloutAccessoryView定制calloutView?)
动态修改calloutView的label
遍历calloutView的subViews,找到UILabel类型的subView,修改其文本即可。
完全自定义的calloutView
整体原理:设置annotationView的canShowCallout为NO。点击此annotationView时(Select),在相同的坐标增加一个新的annotation。取消点击时(
Deselect),删除此annotation。此annotation的annotationView画为自定义的annotation。
1.选择annotation:-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{ if ([view.annotation isKindOfClass:[DearAnnotation class]]) { if (calloutAnnotation) { [mapView removeAnnotation:calloutAnnotation]; calloutAnnotation = nil; } DearPeropertyItem *item; for (item in dearArray){ if (view.annotation == item.annotation){ break; } } calloutAnnotation = [[DearCallOutAnnotation alloc]initWithLocation:item.annotation.coordinate]; calloutDear = item; if (item.annotation.timer != nil){ item.annotation.calloutAnno = calloutAnnotation; item.annotation.moveCallOut = YES; } [mapView addAnnotation:calloutAnnotation]; } }
2.取消选择annotation:-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{ if (calloutAnnotation){ [mapView removeAnnotation:calloutAnnotation]; calloutAnnotation = nil; } }
3.自定义annotationView作为calloutView,在viewForAnnotation时返回
包含绘制calloutView的外框和箭头
// // DearCallOutView.m // Here // // Created by 王栋 on 14/11/4. // Copyright (c) 2014年 王栋. All rights reserved. // #import "DearCallOutView.h" @implementation DearCallOutView #define Arror_height 6 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { } return self; } -(id)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier Name:(NSString *)name{ self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; if (self) { UIFont *font = [UIFont systemFontOfSize:11]; CGSize size = [name sizeWithFont:font constrainedToSize:CGSizeMake(MAXFLOAT, 20)]; // CGSize size = [str sizeWithFont:label.font constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; self.backgroundColor = [UIColor clearColor]; self.canShowCallout = NO; self.centerOffset = CGPointMake(0, -58-20); self.frame = CGRectMake(0, 0, 200, 58+6); self.contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height-6)]; self.contentView.layer.cornerRadius = 10; // self.contentView.backgroundColor = [UIColor whiteColor]; self.contentView.clipsToBounds = YES; // [self.contentView.layer setBorderWidth:0.5]; // [self.contentView.layer setBorderColor:[[UIColor lightGrayColor] CGColor]]; UIColor *color = [UIColor colorWithRed:0 green:122/255.0 blue:1 alpha:1]; _timeLabel = [[UILabel alloc]initWithFrame:CGRectMake(7, 7, 55, 11)]; _timeLabel.font = [UIFont systemFontOfSize:11]; _timeLabel.textColor = color; _timeLabel.text = @"20s前"; _nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(55+14, 7, size.width, 11)]; _nameLabel.font = [UIFont systemFontOfSize:11]; _nameLabel.textColor = color; _distanceLabel = [[UILabel alloc]initWithFrame:CGRectMake(7, 24 , 55, 27)]; _distanceLabel.font = [UIFont systemFontOfSize:27]; _weizhiLabel = [[UILabel alloc]initWithFrame:CGRectMake(55+14, 24, 200-21-55, 27)]; _weizhiLabel.font = [UIFont systemFontOfSize:11]; _weizhiLabel.lineBreakMode = NSLineBreakByWordWrapping|NSLineBreakByTruncatingTail; _weizhiLabel.numberOfLines = 0; _weizhiLabel.textColor = [UIColor darkGrayColor]; UIImageView *bluetooth = [[UIImageView alloc]initWithFrame:CGRectMake(200-7-23-7-21, 8, 21, 10)]; bluetooth.image = [UIImage imageNamed:@"image_track_bluetooth_signal_3.png"]; UIImageView *battery = [[UIImageView alloc]initWithFrame:CGRectMake(200-7-23, 8, 23, 9)]; battery.image = [UIImage imageNamed:@"image_track_battery_background.png"]; _batteryIndicator = [[UIView alloc]initWithFrame:CGRectMake(1, 1, 19, 7)]; _batteryIndicator.backgroundColor = color; [battery addSubview:_batteryIndicator]; [self.contentView addSubview:_timeLabel]; [self.contentView addSubview:_nameLabel]; [self.contentView addSubview:_distanceLabel]; [self.contentView addSubview:_weizhiLabel]; [self.contentView addSubview:battery]; [self.contentView addSubview:bluetooth]; [self addSubview:self.contentView]; return self; } return nil; } - (UIImage*)createImageWithPic:(UIImageView*)pic inImage:(UIImage*)annoImage{ UIGraphicsBeginImageContextWithOptions(annoImage.size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); [annoImage drawInRect:CGRectMake(0, 0, annoImage.size.width, annoImage.size.height)]; CGContextTranslateCTM(context, 2, 2); [pic.layer renderInContext:context]; CGContextTranslateCTM(context, -2, -2); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } - (void)setBattery:(NSInteger)battery{ CGRect frame = _batteryIndicator.frame; frame.size.width = 19.0/100*battery; _batteryIndicator.frame = frame; } -(void)drawRect:(CGRect)rect{ [self drawInContext:UIGraphicsGetCurrentContext()]; } -(void)drawInContext:(CGContextRef)context { CGContextSetLineWidth(context, 2.0); CGContextSetFillColorWithColor(context, [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0].CGColor); [self getDrawPath:context]; CGContextFillPath(context); } - (void)getDrawPath:(CGContextRef)context//自定义annotation calloutView的边框 { CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextSetLineWidth(context, 0.5); CGRect rrect = self.bounds; CGFloat radius = 10; CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); CGFloat miny = CGRectGetMinY(rrect), // midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect)-Arror_height; CGContextMoveToPoint(context, midx+Arror_height, maxy); CGContextAddLineToPoint(context,midx, maxy+Arror_height); CGContextAddLineToPoint(context,midx-Arror_height, maxy); CGContextAddArcToPoint(context, minx, maxy, minx, miny, radius); CGContextAddArcToPoint(context, minx, miny, maxx, miny, radius); CGContextAddArcToPoint(context, maxx, miny, maxx, maxx, radius); CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); CGContextAddLineToPoint(context, midx+Arror_height, maxy); CGContextFillPath(context); CGContextClosePath(context); CGContextMoveToPoint(context, midx+Arror_height, maxy); CGContextAddLineToPoint(context,midx, maxy+Arror_height); CGContextAddLineToPoint(context,midx-Arror_height, maxy); CGContextAddArcToPoint(context, minx, maxy, minx, miny, radius); CGContextAddArcToPoint(context, minx, miny, maxx, miny, radius); CGContextAddArcToPoint(context, maxx, miny, maxx, maxx, radius); CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); // CGContextAddLineToPoint(context, midx+Arror_height, maxy); CGContextClosePath(context); CGContextStrokePath(context); } @end