要达到的效果图
一.首先看下地图中最基础的大头针的定制:
#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;
}
到此.气泡的点击事件就可以实现了.