demo模式:非ARC,使用storyboard。

demo资源:

http://download.csdn.net/detail/mad1989/5252037

Step1

创建demo,并添加百度地图的静态类库,helloword能显示mapview

关于这一步我专门写了教程,这里就不再赘述,同样,关于如何使用自带的BMKPointAnnotation添加一个marker,我也不再说了,如果连这个你都不会,那么先去官网看一下基本教程。

Step2

实现三个委托方法:

这个方法类似tableview添加cell,都是创建annotation

#pragma mark

#pragma mark - BMKMapview delegate

-(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id)annotation;

这个方法在点击地图marker时所触发(并显示callout)

-(void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view;

这个方法在点击地图任意位置,相当于隐藏callout

-(void)mapView:(BMKMapView *)mapView didDeselectAnnotationView:(BMKAnnotationView *)view;

原理:地图上的marker是在viewForAnnoation里创建的,同时也会

隐含的为我们创建一个CalloutView,就是自带的吹出框,只是我们看不到源码。其实这个吹出框(CalloutView)也是一个

annotation,也会在viewForAnnotation里被创建,他的坐标应该和这个点的marker坐标一样,只要明白了这一点,就行了,marker和吹出框是两个不同的annotation,他们有同样的coordinate。

Step3

自定义一个Annotation,为了简单方便,我就直接继承了mapview自带的BMKPointAnnotation,这是一个经典的图钉marker。

在这里我添加了一个Dictionary属性,目的是为了自定义的CalloutView吹出框显示内容赋值,一会就明白了。

Step4

添加自定义Annotation到mapview

//添加自定义Annotation

CLLocationCoordinate2D center = {39.91669,116.39716};

CustomPointAnnotation *pointAnnotation = [[CustomPointAnnotation alloc] init];

pointAnnotation.title = @"我是中国人";//因为继承了BMKPointAnnotation,所以这些title,subtitle都可以设置

pointAnnotation.subtitle = @"我爱自己的祖国";

pointAnnotation.coordinate = center;

[mymapview addAnnotation:pointAnnotation];

[pointAnnotation release];

在viewForanntion里,由于我对marker没太大要求,直接使用了BMKPinAnnotationView(图钉),简单设置image属性为自己需要的图标,如下所示:

展示一个效果图:

显然CalloutView只能设置title和subtitle,无法满足我们的要求,那么继续下一步。

Step5

创建一个(自定义的CalloutView)的Annotation,相当于显示calloutView的annotation。

[注意]

继承自NSObject<BMKAnnotation>

CalloutMapAnnotation.h

#import

#import "BMapKit.h"

@interface CalloutMapAnnotation : NSObject

@property (nonatomic) CLLocationDegrees latitude;

@property (nonatomic) CLLocationDegrees longitude;

@property(retain,nonatomic) NSDictionary *locationInfo;//callout吹出框要显示的各信息

- (id)initWithLatitude:(CLLocationDegrees)lat andLongitude:(CLLocationDegrees)lon;

@end

CalloutMapAnnotation.m

#import "CalloutMapAnnotation.h"

@implementation CalloutMapAnnotation

@synthesize latitude;

@synthesize longitude;

@synthesize locationInfo;

- (id)initWithLatitude:(CLLocationDegrees)lat

andLongitude:(CLLocationDegrees)lon {

if (self = [super init]) {

self.latitude = lat;

self.longitude = lon;

}

return self;

}

-(CLLocationCoordinate2D)coordinate{

CLLocationCoordinate2D coordinate;

coordinate.latitude = self.latitude;

coordinate.longitude = self.longitude;

return coordinate;

}

@end

这里设置了经纬度的属性,和一个init初始化经纬度的方法(经纬度=marker的经纬度),同样添加了一个Dictionary的属性,为了传递在CalloutView上内容的赋值,继续。

Step6

这一步我们创建自定义的View,想要什么布局就写什么样的布局,想要多少属性就加多少属性,这里我使用了code方式画了一个contentView,里面的子view使用Xib方式创建。

[注意:继承自BMKAnnotationView]

CallOutAnnotationView.h

#import "BMKAnnotationView.h"

#import "BusPointCell.h"

@interface CallOutAnnotationView : BMKAnnotationView

@property(nonatomic,retain) UIView *contentView;

//添加一个UIView

@property(nonatomic,retain) BusPointCell *busInfoView;//在创建calloutView Annotation时,把contentView add的 subview赋值给businfoView

@end

BusPointCell是ContentView里的subview,这个view就是显示各个组件,并赋不同的值

CallOutAnnotationView.m

#import "CallOutAnnotationView.h"

#import

#define Arror_height 6

@implementation CallOutAnnotationView

@synthesize contentView;

@synthesize busInfoView;

- (id)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if (self) {

}

return self;

}

-(void)dealloc{

[contentView release];

[busInfoView release];

[super dealloc];

}

-(id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier{

self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];

if (self) {

self.backgroundColor = [UIColor clearColor];

self.canShowCallout = NO;

self.centerOffset = CGPointMake(0, -55);

self.frame = CGRectMake(0, 0, 240, 80);

UIView *_contentView = [[UIView alloc] initWithFrame:CGRectMake(5, 5, self.frame.size.width-15, self.frame.size.height-15)];

_contentView.backgroundColor = [UIColor clearColor];

[self addSubview:_contentView];

self.contentView = _contentView;

[_contentView release];

}

return self;

}

-(void)drawRect:(CGRect)rect{

[self drawInContext:UIGraphicsGetCurrentContext()];

self.layer.shadowColor = [[UIColor blackColor] CGColor];

self.layer.shadowOpacity = 1.0;

self.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);

}

-(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

{

CGRect rrect = self.bounds;

CGFloat radius = 6.0;

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, minx, maxx, miny, radius);

CGContextAddArcToPoint(context, maxx, miny, maxx, maxx, radius);

CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);

CGContextClosePath(context);

}

@end

BusPointCell.h

想要多少label,就可以有多少label

#import

@interface BusPointCell : UIView

@property (retain, nonatomic) IBOutlet UILabel *aliasLabel;

@property (retain, nonatomic) IBOutlet UILabel *speedLabel;

@property (retain, nonatomic) IBOutlet UILabel *degreeLabel;

@property (retain, nonatomic) IBOutlet UILabel *nameLabel;

@end

BusPointCell.m

#import "BusPointCell.h"

@implementation BusPointCell

- (id)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if (self) {

}

return self;

}

- (void)dealloc {

[_aliasLabel release];

[_speedLabel release];

[_degreeLabel release];

[_nameLabel release];

[super dealloc];

}

@end

BusPointCell.xib

Step7

自定义的CalloutView都准备妥当,现在就是要实现他们的部分了,简单说一下原理,在didSelectAnnotationView函数里创建并添加calloutview的annotation(CalloutMapAnnotation),然后在viewForAnnotation函数内实例化要显示的calloutview(CallOutAnnotationView)

首先声明一个局部变量CalloutMapAnnotation *_calloutMapAnnotation;

在didSelectAnnotationView函数内添加如下代码:

//CustomPointAnnotation 是自定义的marker标注点,通过这个来得到添加marker时设置的pointCalloutInfo属性

CustomPointAnnotation *annn = (CustomPointAnnotation*)view.annotation;

if ([view.annotation isKindOfClass:[CustomPointAnnotation class]]) {

//如果点到了这个marker点,什么也不做

if (_calloutMapAnnotation.coordinate.latitude == view.annotation.coordinate.latitude&&

_calloutMapAnnotation.coordinate.longitude == view.annotation.coordinate.longitude) {

return;

}

//如果当前显示着calloutview,又触发了select方法,删除这个calloutview annotation

if (_calloutMapAnnotation) {

[mapView removeAnnotation:_calloutMapAnnotation];

_calloutMapAnnotation=nil;

}

//创建搭载自定义calloutview的annotation

_calloutMapAnnotation = [[[CalloutMapAnnotation alloc] initWithLatitude:view.annotation.coordinate.latitude andLongitude:view.annotation.coordinate.longitude] autorelease];

//把通过marker(ZNBCPointAnnotation)设置的pointCalloutInfo信息赋值给CalloutMapAnnotation

_calloutMapAnnotation.locationInfo = annn.pointCalloutInfo;

[mapView addAnnotation:_calloutMapAnnotation];

[mapView setCenterCoordinate:view.annotation.coordinate animated:YES];

}

其次,要在viewForAnnotation里创建我们的calloutview(CallOutAnnotationView),添加如下代码:

else if ([annotation isKindOfClass:[CalloutMapAnnotation class]]){

//此时annotation就是我们calloutview的annotation

CalloutMapAnnotation *ann = (CalloutMapAnnotation*)annotation;

//如果可以重用

CallOutAnnotationView *calloutannotationview = (CallOutAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"calloutview"];

//否则创建新的calloutView

if (!calloutannotationview) {

calloutannotationview = [[[CallOutAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"calloutview"] autorelease];

BusPointCell *cell = [[[NSBundle mainBundle] loadNibNamed:@"BusPointCell" owner:self options:nil] objectAtIndex:0];

[calloutannotationview.contentView addSubview:cell];

calloutannotationview.busInfoView = cell;

}

//开始设置添加marker时的赋值

calloutannotationview.busInfoView.aliasLabel.text = [ann.locationInfo objectForKey:@"alias"];

calloutannotationview.busInfoView.speedLabel.text = [ann.locationInfo objectForKey:@"speed"];

calloutannotationview.busInfoView.degreeLabel.text =[ann.locationInfo objectForKey:@"degree"];

calloutannotationview.busInfoView.nameLabel.text = [ann.locationInfo objectForKey:@"name"];

return calloutannotationview;

}

[注意]在添加marker的判断里一定要设置markerannotation.canShowCallout =NO;

否则点击marker会默认显示系统的吹出框

Step8

calloutview的annotation也创建和添加了,接下来我们就设置一下marker对应吹出框的数据:

然后运行一下:

哈哈!搞定了吧,具体布局可以自己通过code方式,或xib方式设计,目前点击marker能显示了,可是点击其它区域还是无法显示,所以我们在didDeselectAnnotationView方法里还需要判断一下,remove掉。

-(void)mapView:(BMKMapView *)mapView didDeselectAnnotationView:(BMKAnnotationView *)view{

if (_calloutMapAnnotation&&![view isKindOfClass:[CallOutAnnotationView class]]) {

if (_calloutMapAnnotation.coordinate.latitude == view.annotation.coordinate.latitude&&

_calloutMapAnnotation.coordinate.longitude == view.annotation.coordinate.longitude) {

[mapView removeAnnotation:_calloutMapAnnotation];

_calloutMapAnnotation = nil;

}

}

}

最后

之所以在显示marker的annotation[本文为CustomPointAnnotation]和显示calloutview的annotation[本文为CalloutMapAnnotation]里各添加一个Dictionary,就是要在点击时通过marker传递数据,添加时通过calloutview的annotation实例来设置每一个属性的数据,已达到不同的maker,显示不同的数据。

可能我的过程不是太清晰,自己仔细研究一下这三个函数和mapview自带的callout调用过程,便会明白。

android百度地图 自定义气泡,百度地图自定义吹出框(气泡)(转)相关推荐

  1. 百度地图自定义吹出框

    2019独角兽企业重金招聘Python工程师标准>>> 百度地图自定义吹出框 直入正题吧! 这些都是知道的了,看文档添加就行了! 实现三个代理方法: 这个方法类似tableview添 ...

  2. ios 一步一步学会自定义地图吹出框(CalloutView)--(百度地图,高德地图,google地图)

    前言 在ios上边使用地图库的同学肯定遇到过这样的问题:吹出框只能设置title和subtitle和左右的view,不管是百度地图还是高德地图还是自带的google地图,只提供了这四个属性,如果想添加 ...

  3. Android自定义弹窗模仿微信,Android 仿微信朋友圈点赞和评论弹出框功能

    本文简单模仿微信朋友圈的点赞和评论弹出框,布局等细节请忽略,着重实现弹出框.发评论,及弹出位置的控制. 1. 微信弹出框 微信朋友圈的点赞和评论功能,有2个组成部分: 点击左下角的"更多&q ...

  4. messagrbox自定义按钮c语言,基于dialogbox修改可自定义按钮及事件的弹出框插件

    插件描述:基于dialogbox1.0修改可自定义按钮及事件的弹出框插件,每个按钮可绑定单独的触发事件,并且能支持将弹出框作为一个表单来填入数据并获取 $('body').dialogbox({ ty ...

  5. android 蒙版图片带拖动_Android实现蒙版弹出框效果

    本文实例为大家分享了android蒙版弹出框效果的具体代码,供大家参考,具体内容如下 自定义 package cn.lxsdb.yyd.app.dialog; import cn.lxsdb.yyd. ...

  6. android 弹窗有边框_Android 多种简单的弹出框样式设置代码

    简介 这是一个基于AlertDialog和Dialog这两个类封装的多种弹出框样式,其中提供各种简单样式的弹出框使用说明.同时也可自定义弹出框. 特性 1.使用链式开发代码简洁明了 2.所有的弹出框样 ...

  7. Android:仿QQ 发表说说/上传照片 弹出框

    代码很简单,主要就是几个动画而已,图标什么的就随便找了几个,效果图:      动画说明: 1.点击右上角按钮,菜单从顶部下拉弹出,同时背景变暗; 2.再次点击右上角按钮,点击返回键,或者点击空白区域 ...

  8. OpenLayers标记地图点及点击地图点显示自定义弹出框

    css代码(设置弹出框样式) /*设置弹出框样式*/.ol-popup {position: absolute;background-color: #eeeeee;-webkit-filter: dr ...

  9. android百度地图定位自定义图标,百度地图SDK集成及根据坐标实现定位(android studio开发)...

    百度地图SDK集成及根据坐标实现定位(android studio开发) 百度地图SDK集成及根据坐标实现定位(android studio开发) 1.下载百度地图SDK 链接:http://lbsy ...

最新文章

  1. 快速完整的基于点云闭环检测的激光SLAM系统
  2. 最长连续子序列偏移_最长连续不重复子序列
  3. 通过Easy-UI 树插件实现ArcGIS多个服务图层的图层控制
  4. kernel 中标准的 ir 模块的 时间的定义_Linux开机流程详解:BIOSgt;MBRgt;GRUBgt;Kernel...
  5. opencv 直线检测 java_OpenCV实现图像的直线检测
  6. 作者:Ochora Dennis Reagan(1990-),男,东北大学软件学院硕士生
  7. linux的虚拟内存是4G,而每个进程都有自己独立的4G内存空间,怎么理解?
  8. STL之multiset简介
  9. 2021-08-04 WHERE条件查询
  10. Java连接数据库实现增删改;查。
  11. 2.线程和进程的含义和区别,进程间通信方式有哪些?
  12. CSP 201903-5 317号子任务 暴力30分+优化100分
  13. 房东违反房屋租赁合同会怎么进行赔偿
  14. 仿微信.QQ聊天界面
  15. ValueError: You are trying to load a weight file containing 0 layers into a model with 16 layers.
  16. 使用git拉取远程仓库代码
  17. PCB常见的几种钻孔
  18. 苹果这波是要偷家啊。。
  19. NAS自动挂载和关闭硬盘电源原理
  20. 国内黑客组织及代表性人物

热门文章

  1. [uni-app] 微信小程序 如何修改替换头像
  2. 访问控制模型详细介绍
  3. 调整字体间距属性和文字换行属性
  4. ddtv.space index.php,图解MongoDB原理(二)
  5. POJ 1061 青蛙的约会(扩展GCD求模线性方程)
  6. dropout 关于keep_prob
  7. 君子慎独,卑以自牧!
  8. [转]XML详解--Schema
  9. Variable Generator/dense/kernel already exists, disallowed.
  10. 看你骨骼清奇,老夫决定赐你这份“2018软件测试发光秘籍”