高德地图上可以添加覆盖物和标注物(如定位大头针)。
覆盖物MAGroundOverlay会随着地图的放大缩小而等比例的放大缩小,优点页很显然,移动带有大量覆盖物的地图,覆盖物不闪动,很平滑。
标注物MAAnnotationView不会随着地图的放大缩小而改变。缺点是当地图上有大量标注物时,上下左右的移动地图,标注物会有闪动的效果,不平滑(安卓的高德3D地图没有该问题)。若标注物有点击事件,在创建标注物时一定要给它具体的frame,不然会可能看到了标注物大小正常,但是当两个标注物冲动或比较近时,可能误判点击的是那个标注物。这个问题当时难住我三天,后来通过不断试探才找到这个问题的解决方案。具体的代码就是:
annotationView.frame = CGRectMake(0, 0, 32, 42); annotationView.image = [UIImage bundleName:@"LChat_RedPacketModule" imageNamed:@"red_business"]; annotationView.imageView.frame = CGRectMake(0, 0, 32, 42);
具体的完整使用代码:
LCCustomCalloutView.h:
#import <UIKit/UIKit.h> #import "LCListRedPacketUnitEntity.h" #import "LCSameCitySearchUnitEntity.h" @import MAMapKit; /**分享的图片最大宽度,单位:ps像素(不是物理像素)*/ #define sIconMapImageWidth 32 #define sIconMapImageHeight 42 @interface LCCustomCalloutView : MAAnnotationView //@property (nonatomic, strong, readwrite) LCCustomCalloutView *calloutView; @property (nonatomic) CGRect mapFrame; @property (nonatomic,strong) UIImageView *iconImage; @property (nonatomic, strong) LCListRedPacketUnitEntity *model; @property (nonatomic, strong) LCSameCitySearchUnitEntity *sameCitySearchUnitEntity; @property (nonatomic, copy) void(^selectBlock)(LCListRedPacketUnitEntity *model); @property (nonatomic, copy) void(^selectSearchBlock)(LCSameCitySearchUnitEntity *sameCitySearchUnitEntity); @property (nonatomic, strong) MAPointAnnotation *pointAnnotation; @end
LCCustomCalloutView.m文件:
#import "LCCustomCalloutView.h" //#import "NSString+Extension.h" @interface LCCustomCalloutView () @property (nonatomic,strong) UILabel *chatelainAddressLabel; @property (nonatomic,strong) UILabel *incomeDescriptionLabel; @property (nonatomic,strong) UILabel *incomeLabel; @property (nonatomic,strong) UILabel *btnTitleLabel; @property (nonatomic,strong) UIImageView *chatelainAvatarImageView; @property (nonatomic,strong) UIButton *btn; //@property (nonatomic,strong) UIImageView *iconImage; @end @implementation LCCustomCalloutView - (instancetype)initWithFrame:(CGRect)frame{ if (self=[super initWithFrame:frame ]) { [self addchildV]; } return self; } - (void)addchildV { [self iputSubPanel]; } - (void)iputSubPanel { } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { BOOL isHaveSingleTap = NO; UIView *touched = [[touches anyObject] view]; for (UITouch *aTouch in touches) { NSLog(@"aTouch.tapCount:%d, aTouch.type:%d, aTouch.phase:%d",aTouch.tapCount, aTouch.type, aTouch.phase) if (aTouch.tapCount == 1) { isHaveSingleTap = YES; } } if(!isHaveSingleTap) { return; } //获取点击点的坐标 CGPoint touchPoint = [[touches anyObject] locationInView:self]; //空白处的范围 CGRect rect = CGRectMake(0, 0, 32, 42); //判断 点(CGPoint)是否在某个范围(CGRect)内 if (!CGRectContainsPoint(rect, touchPoint)) { return; } NSLog(@"touchPoint.x:%f,touchPoint.y:%f, self.bounds.size.width:%f,self.bounds.size.height:%f",touchPoint.x,touchPoint.y, self.bounds.size.width,self.bounds.size.height); self.canShowCallout = NO; for (UIView *v in self.subviews) { // if ([v isKindOfClass:[UIButton class]] ) { if([v isKindOfClass:[UIImageView class]]) { if(v == self.imageView) { // if(self.model && [self.model isKindOfClass:[LCListRedPacketUnitEntity class]]) { if(self.selectBlock) { self.selectBlock(self.model); } if(self.selectSearchBlock) { self.selectSearchBlock(self.sameCitySearchUnitEntity); } return; } } } } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { } -(UIImageView *)iconImage{ if (!_iconImage) { _iconImage = [UIImageView new]; _iconImage.backgroundColor = [UIColor clearColor]; } return _iconImage; } - (void)setModel:(LCListRedPacketUnitEntity *)model { // self.frame = CGRectMake(0, 0, 32, 42); self.backgroundColor = [UIColor clearColor]; if(!model || ![model isKindOfClass:[LCListRedPacketUnitEntity class]]) { return; } self.canShowCallout = NO; _model = model; if(!_iconImage) { [self addSubview:self.iconImage]; self.iconImage.sd_layout .leftSpaceToView(self, 0) .topSpaceToView(self, 0) .widthIs(32) .heightIs(42); // 设置高度约束 [self addAnimation]; } model.iconImage = _iconImage; if([[QYSingleObject sharedInstance] achiveStringWithWeb:model.cover]) { [self.iconImage sd_setImageWithURL:[NSURL URLWithString:model.cover]]; } } - (void)addAnimation { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; // 动画选项设定 animation.duration = .5; // 动画持续时间 animation.repeatCount = NSIntegerMax; // 重复次数 animation.autoreverses = YES; // 动画结束时执行逆动画 // 缩放倍数 animation.fromValue = [NSNumber numberWithFloat:1.0]; // 开始时的倍率 animation.toValue = [NSNumber numberWithFloat:1.2]; // 结束时的倍率 // 添加动画 [self.iconImage.layer addAnimation:animation forKey:@"scale-layer"]; } - (void)setSameCitySearchUnitEntity:(LCSameCitySearchUnitEntity *)sameCitySearchUnitEntity { // self.frame = CGRectMake(0, 0, 32, 42); self.backgroundColor = [UIColor clearColor]; if(!sameCitySearchUnitEntity || ![sameCitySearchUnitEntity isKindOfClass:[LCSameCitySearchUnitEntity class]]) { return; } self.canShowCallout = NO; _sameCitySearchUnitEntity = sameCitySearchUnitEntity; if(!_iconImage) { [self addSubview:self.iconImage]; self.iconImage.contentMode = UIViewContentModeScaleAspectFit; self.iconImage.clipsToBounds = YES; self.iconImage.sd_layout .leftSpaceToView(self, 0) .topSpaceToView(self, 0) .widthIs(32) .heightIs(42); // 设置高度约束 [self addAnimation]; } sameCitySearchUnitEntity.iconImage = _iconImage; if([[QYSingleObject sharedInstance] achiveStringWithWeb:sameCitySearchUnitEntity.cover]) { [self.iconImage sd_setImageWithURL:[NSURL URLWithString:sameCitySearchUnitEntity.cover]]; } } @end
添加标注物代码:
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation { self.mapView.showsCompass= NO; self.mapView.showsScale = NO; if ([annotation isKindOfClass:[MAPointAnnotation class]]) { NSLog(@"annotation:%@", [annotation class]); if([annotation isKindOfClass:[MAUserLocation class]]) { NSString *annotationReuseIndetifierMAUserLocation = @"annotationReuseIndetifierMAUserLocation"; MAAnnotationView *annotationView = (MAAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationReuseIndetifierMAUserLocation]; if (annotationView == nil) { annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationReuseIndetifierMAUserLocation]; annotationView.image =[UIImage bundleName:@"LChat_RedPacketModule" imageNamed:@"red_user_location"]; } self.mapView.showsCompass= NO; self.mapView.showsScale = NO; return annotationView; } if(annotation == self.topPointAnnotation || annotation == self.bottomPointAnnotation) { NSString *reuseIndetifier = @"topPointAnnotationReuseIndetifier"; if(annotation == self.bottomPointAnnotation) { reuseIndetifier = @"bottomPointAnnotationReuseIndetifier"; } LCCustomCalloutView *annotationView = (LCCustomCalloutView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier]; if (annotationView == nil) { annotationView = [[LCCustomCalloutView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIndetifier]; } annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO annotationView.imageView.userInteractionEnabled = YES; annotationView.draggable = NO; //设置标注可以拖动,默认为NO @weakify(self); annotationView.selectBlock = ^(LCListRedPacketUnitEntity *model) { @strongify(self); sJumpLoginWithToken(LKUSER.token); LKTaskViewController *vc = LKTaskViewController.new; vc.titleStr = @""; vc.isHaveNavi = NO; vc.fullUrl = [NSString stringWithFormat:@"%@hongbao/#/pages/invitation/invitation?token=%@",[GBSwitchEnvironment sharedEnvironment].currentENV.h5BaseHeadURL,LKUSER.token];; [[BITNavigationController currentNavigationController] pushViewController:vc animated:YES]; }; annotationView.frame = CGRectMake(0, 0, 32, 42); annotationView.image = [UIImage bundleName:@"LChat_RedPacketModule" imageNamed:@"red_business"]; annotationView.imageView.frame = CGRectMake(0, 0, 32, 42); return annotationView; } LCListRedPacketUnitEntity *listRedPacketUnitEntity = [self.entity.listRedPacketEntity getListRedPacketUnitEntityWithPointAnnotation:annotation]; if(!listRedPacketUnitEntity) { return nil; } if(![listRedPacketUnitEntity isKindOfClass:[LCListRedPacketUnitEntity class]] || (self.entity.listRedPacketEntity.filterSurprise && 1 == listRedPacketUnitEntity.redPacketType) || listRedPacketUnitEntity.noDisplay) { return nil; } NSString *reuseIndetifier = [NSString stringWithFormat:@"annotationReuseIndetifier%d", listRedPacketUnitEntity.sno]; LCCustomCalloutView *annotationView = (LCCustomCalloutView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier]; if (annotationView == nil) { annotationView = [[LCCustomCalloutView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIndetifier]; } annotationView.frame = CGRectMake(0, 0, 32, 42); annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO annotationView.draggable = NO; //设置标注可以拖动,默认为NO __weak typeof(annotationView) weakAnnotationView= annotationView; __weak typeof(listRedPacketUnitEntity) weakListRedPacketUnitEntity= listRedPacketUnitEntity; @weakify(self); annotationView.selectBlock = ^(LCListRedPacketUnitEntity *model) { @strongify(self); __strong typeof(weakAnnotationView) strongAnnotationView = weakAnnotationView; __strong typeof(weakListRedPacketUnitEntity) strongListRedPacketUnitEntity = weakListRedPacketUnitEntity; self.selectPointAnnotation = strongListRedPacketUnitEntity.pointAnnotation; self.entity.redPacketClickEntity.redPacketId = strongListRedPacketUnitEntity.redPacketId; self.entity.redPacketClickEntity.userId = strongListRedPacketUnitEntity.userId; [self excuteRedPacketClickCommand]; }; annotationView.frame = CGRectMake(0, 0, 32, 42); annotationView.imageView.userInteractionEnabled = YES; annotationView.image = [UIImage qmui_imageWithColor:[UIColor colorWithWhite:1 alpha:0.0] size:CGSizeMake(32, 42) cornerRadius:0]; return annotationView; } return nil; }