自定义annotationView和calloutView

自定义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
原文地址:https://www.cnblogs.com/zhongriqianqian/p/4140025.html