地图大头针和气泡callout的自定制,以及气泡的点击事件

要达到的效果图

Snip20170727_7.png

一.首先看下地图中最基础的大头针的定制:

#import 
#import "CustomCalloutView.h"//自定制气泡callout
#import "LLAllCarModel.h" //处理数据的model
@interface CustomAnnotationView : MAAnnotationView
@property (nonatomic, readonly) CustomCalloutView *calloutView;
@property (nonatomic, strong) LLAllCarModel  *mod;

//这两个block就是实现点击callout上面的按钮实现相应的点击事件(原理就是将CustomAnnotationView上的两个button返回到主ViewController中)
@property (nonatomic, copy) void(^sumButtonClickBlock)(CustomAnnotationView *annoView);
@property (nonatomic, copy) void(^historyButtonClickBlock)(CustomAnnotationView *annoView);

- (void)refreshAnnotationData:(LLAllCarModel *)model;

@end





#import "CustomAnnotationView.h"
#define kCalloutWidth       130.0
#define kCalloutHeight      210.0
@interface CustomAnnotationView()
@property (nonatomic, strong, readwrite) CustomCalloutView *calloutView;

@end

@implementation CustomAnnotationView

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
    if (self.selected == selected) {
        return;
    }
    if (selected) {
        if (self.calloutView == nil) {
            self.calloutView = [[CustomCalloutView alloc] initWithFrame:CGRectMake(0, 0, kCalloutWidth, kCalloutHeight)];
            _calloutView.userInteractionEnabled = YES;
            self.calloutOffset = CGPointMake(0, -66);
            self.calloutView.center = CGPointMake(CGRectGetWidth(self.bounds) / 2.0 + self.calloutOffset.x, -CGRectGetHeight(self.bounds) / 2.0 + self.calloutOffset.y);
        }
        //callout按钮的点击事件
            [self.calloutView.sumBtn addTarget:self action:@selector(onSumBtnClick) forControlEvents:UIControlEventTouchUpInside];
            [self.calloutView.historyBtn addTarget:self action:@selector(onHistoryBtnClick) forControlEvents:UIControlEventTouchUpInside];
        
        [self.calloutView refreshnewData:_mod];
        
        [self addSubview:_calloutView];
    }else{
        [self.calloutView removeFromSuperview];
    }
    [super setSelected:selected animated:animated];
    
}

- (void)refreshAnnotationData:(LLAllCarModel *)model{
    _mod = model;
    
}
//将单击事件回传到viewcontroller中
- (void)onSumBtnClick {
    if(self.sumButtonClickBlock) {
        self.sumButtonClickBlock(self);
    }
}
//将单击事件回传到viewcontroller中
- (void)onHistoryBtnClick {
    if(self.historyButtonClickBlock) {
        self.historyButtonClickBlock(self);
    }
}
//重写hitTest方法是点击callOut上的按钮有效
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView *view = [super hitTest:point withEvent:event];
    [view addSubview:_sumButton];
    [view addSubview:_historyButton];
    if (view == nil) {
        CGPoint sumPoint = [self.calloutView.sumBtn convertPoint:point fromView:self];
        if (CGRectContainsPoint(self.calloutView.sumBtn.bounds, sumPoint)) {
            view = self.calloutView.sumBtn;
            NSLog(@"11111111111111111");
            return view;
            
        }
        CGPoint hisPoint = [self.calloutView.historyBtn convertPoint:point fromView:self];
        if (CGRectContainsPoint(self.calloutView.historyBtn.bounds, hisPoint)) {
            view = self.calloutView.historyBtn;
            NSLog(@"22222222222222222222");
            return view;
        }
    }
    return view;

}

二.看下气泡callout的自定制

#import 
#import "LLAllCarModel.h"

@interface CustomCalloutView : UIView

@property (nonatomic, strong) UILabel *imeiL;
@property (nonatomic, strong) UILabel *statusL;
@property (nonatomic, strong) UILabel *temperL;
@property (nonatomic, strong) UIImageView *gpsL;
@property (nonatomic, strong) UIImageView *gsmL;

@property (nonatomic, strong) UIButton *sumBtn;//里程统计
@property (nonatomic, strong) UIButton *historyBtn;//历史轨迹
//这两个block就是实现点击callout上面的按钮实现相应的点击事件(原理就是将CustomAnnotationView上的两个button返回到主ViewController中)
@property (nonatomic, copy) void(^sumButtonClickBlock)(CustomAnnotationView *annoView);
@property (nonatomic, copy) void(^historyButtonClickBlock)(CustomAnnotationView *annoView);

- (void)refreshnewData:(LLAllCarModel *)model;

@end



#import "CustomCalloutView.h"
#define kArrorHeight        10
@implementation CustomCalloutView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColor clearColor];
        [self createSubView];
    }
    return self;
}

- (void)createSubView{
    CGFloat gap = 10;
    NSArray *nameLabelArr = @[@"IMEI:",@"状态:",@"温度:",@"GPS:",@"GSM:"];
    for (int i = 0; i < nameLabelArr.count; i ++) {
        UILabel *namesL = [FactoryUI createLabelWithFrame:CGRectMake(gap, gap + 20*i + gap*i, 40, 20) title:nameLabelArr[i] andFont:13];
        [self addSubview:namesL];
        UILabel *subL = [FactoryUI createLabelWithFrame:CGRectMake(CGRectGetMaxX(namesL.frame)+5, CGRectGetMinY(namesL.frame), 70, 20) title:nil andFont:13];
        if (i == 0) {
            _imeiL = subL;
            [self addSubview:_imeiL];
        }else if (i == 1) {
            _statusL = subL;
            [self addSubview:_statusL];
        }else if (i == 2) {
            _temperL = subL;
            [self addSubview:_temperL];
        }else if (i == 3) {
            _gpsL = [FactoryUI createImageViewWithFrame:CGRectMake(CGRectGetMaxX(namesL.frame)+5, CGRectGetMinY(namesL.frame), 20, 20) andImageName:nil];
            [self addSubview:_gpsL];
        }else if (i == 4) {
            _gsmL = [FactoryUI createImageViewWithFrame:CGRectMake(CGRectGetMaxX(namesL.frame)+5, CGRectGetMinY(namesL.frame), 20, 20) andImageName:nil];;
            [self addSubview:_gsmL];
        }
    }
    UILabel *horizentalLine = [FactoryUI createLabelWithFrame:CGRectMake(0, 155, self.bounds.size.width, 0.4) title:nil andFont:1];
    horizentalLine.backgroundColor = [UIColor lightGrayColor];
    [self addSubview:horizentalLine];
    
    _sumBtn = [FactoryUI createButtonWithFrame:CGRectMake(0, CGRectGetMaxY(horizentalLine.frame), self.bounds.size.width / 2.0, self.bounds.size.height - CGRectGetMaxY(horizentalLine.frame)-10) title:@"里程" normalImage:nil selectedImage:nil titleColor:[UIColor colorWithHexString:@"#1989fa"] target:nil selector:nil andTag:12];
    _sumBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    [self addSubview:_sumBtn];
    UILabel *versialLine = [FactoryUI createLabelWithFrame:CGRectMake(self.bounds.size.width/2.0-1, CGRectGetMaxY(horizentalLine.frame), 0.4, CGRectGetHeight(_sumBtn.frame) - 10) title:nil andFont:1];
    versialLine.backgroundColor = [UIColor lightGrayColor];
    [self addSubview:versialLine];
    _historyBtn = [FactoryUI createButtonWithFrame:CGRectMake(CGRectGetMaxX(_sumBtn.frame), CGRectGetMinY(_sumBtn.frame), self.bounds.size.width / 2.0, CGRectGetHeight(_sumBtn.frame)) title:@"轨迹" normalImage:nil selectedImage:nil titleColor:[UIColor colorWithHexString:@"#1989fa"] target:nil selector:nil andTag:21];
    _historyBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    [self addSubview:_historyBtn];
}
//刷新callout上面的数据
- (void)refreshnewData:(LLAllCarModel *)model{
    _imeiL.text = model.name;
    if ([model.status isEqualToString:@"M"]) {
        _statusL.textColor = [UIColor redColor];
        _statusL.text = @"故障";
    }else if ([model.status isEqualToString:@"O"]){
        _statusL.textColor = [UIColor redColor];
        _statusL.text = @"断开";
    }else if ([model.status isEqualToString:@"N"] || [model.status isEqualToString:@"S"]){
        _statusL.textColor = [UIColor greenColor];
        _statusL.text = @"正常";
    }
    
    _temperL.text = model.temper;
    [_gpsL sd_setImageWithURL:[NSURL URLWithString: model.gps]];
    [_gsmL sd_setImageWithURL:[NSURL URLWithString:  model.gsm]];
}

//***************下面这里及时绘制callout的方法***************************
//1.这个是callout背景颜色
- (void)drawRect:(CGRect)rect{
    [self drawInContext:UIGraphicsGetCurrentContext()];
    self.layer.shadowColor = [UIColor whiteColor].CGColor;
    self.layer.shadowOpacity = 0.7;
    self.layer.shadowOffset = CGSizeMake(3.0f, 3.0f);
    
}
//callout填充
- (void)drawInContext:(CGContextRef)context{
    CGContextSetLineWidth(context, 2.0);
    CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:0.8].CGColor);
    
    [self getDrawPath:context];
    CGContextFillPath(context);
}
//划线路径
- (void)getDrawPath:(CGContextRef)context{
    CGRect rrect = self.bounds;
    CGFloat radius = 6;
    CGFloat minx = CGRectGetMinX(rrect),
    midx = CGRectGetMidX(rrect),
    maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect),
    maxy = CGRectGetMaxY(rrect)-kArrorHeight;
    
    CGContextMoveToPoint(context, midx+kArrorHeight, maxy);
    CGContextAddLineToPoint(context,midx, maxy+kArrorHeight);
    CGContextAddLineToPoint(context,midx-kArrorHeight, maxy);
    
    CGContextAddArcToPoint(context, minx, maxy, minx, miny, radius);
    CGContextAddArcToPoint(context, minx, minx, maxx, miny, radius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, maxx, radius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    CGContextClosePath(context);
}

最后在Viewcontroll中显示自定制的大头针和callout

#pragma mark - MAMapViewDelegate
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id )annotation{
    if ([annotation isKindOfClass:[MAPointAnnotation class]]) {
        //标注view 的初始化和复用
        static NSString *reuseString = @"allCatAnnotation";
        CustomAnnotationView *cusAnnotation = (CustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseString];
        if (!cusAnnotation) {
            cusAnnotation = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseString];
        }
        for (LLAllCarModel *model in self.allCarArr) {
            //判断是哪个大头针
            if ([model.lat floatValue] == annotation.coordinate.latitude && [model.lon floatValue] == annotation.coordinate.longitude) {
                
                [cusAnnotation refreshAnnotationData:model];
                
//*********************这里是我要监控CustomAnnotationView里面sumButton和historyButton的单击事件的*******************
               cusAnnotation.sumButtonClickBlock = ^(CustomAnnotationView *annoView) {
                    NSLog(@"点击了model.imei====%@的里程统计",model.imei);
                    LLMSumViewController *sumVC = [[LLMSumViewController alloc] init];
                    sumVC.imeiStr = model.imei;
                    sumVC.nickNameStr = model.name;
                    [self.navigationController pushViewController:sumVC animated:YES];
                };
                cusAnnotation.historyButtonClickBlock = ^(CustomAnnotationView *annoView) {
                    NSLog(@"点击了model.imei====%@的历史轨迹",model.imei);
                    LLhistoryViewController *historyVC = [[LLhistoryViewController alloc] init];
                    historyVC.imeiStr = model.imei;
                    historyVC.nickNameStr = model.name;
                    [self.navigationController pushViewController:historyVC animated:YES];
                };

//************************************************************
            }
        }
        
        
        cusAnnotation.draggable = NO;
        cusAnnotation.canShowCallout = NO;//将自带的关掉
        cusAnnotation.image = [UIImage imageNamed:@"icon_position"];;
        cusAnnotation.centerOffset = CGPointMake(0, -33);
        
        return cusAnnotation;
    }
    return nil;

    
}

到此.气泡的点击事件就可以实现了.

你可能感兴趣的:(地图大头针和气泡callout的自定制,以及气泡的点击事件)