要達(dá)到的效果圖

Snip20170727_7.png
一.首先看下地圖中最基礎(chǔ)的大頭針的定制:
#import <MAMapKit/MAMapKit.h>
#import "CustomCalloutView.h"http://自定制氣泡callout
#import "LLAllCarModel.h" //處理數(shù)據(jù)的model
@interface CustomAnnotationView : MAAnnotationView
@property (nonatomic, readonly) CustomCalloutView *calloutView;
@property (nonatomic, strong) LLAllCarModel *mod;
//這兩個block就是實現(xiàn)點擊callout上面的按鈕實現(xiàn)相應(yīng)的點擊事件(原理就是將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 <UIKit/UIKit.h>
#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;//里程統(tǒng)計
@property (nonatomic, strong) UIButton *historyBtn;//歷史軌跡
//這兩個block就是實現(xiàn)點擊callout上面的按鈕實現(xiàn)相應(yīng)的點擊事件(原理就是將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:",@"狀態(tài):",@"溫度:",@"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上面的數(shù)據(jù)
- (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 <MAAnnotation>)annotation{
if ([annotation isKindOfClass:[MAPointAnnotation class]]) {
//標(biāo)注view 的初始化和復(fù)用
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];
//*********************這里是我要監(jiān)控CustomAnnotationView里面sumButton和historyButton的單擊事件的*******************
cusAnnotation.sumButtonClickBlock = ^(CustomAnnotationView *annoView) {
NSLog(@"點擊了model.imei====%@的里程統(tǒng)計",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;//將自帶的關(guān)掉
cusAnnotation.image = [UIImage imageNamed:@"icon_position"];;
cusAnnotation.centerOffset = CGPointMake(0, -33);
return cusAnnotation;
}
return nil;
}
到此.氣泡的點擊事件就可以實現(xiàn)了.