2016-09-29 10:00:04 qq_28865297 阅读数 3034

在用百度地图点击标注的时候,发现不能够连续点击标注,每次点击标注之后,需要在点击其他地方


/**
 *当选中一个annotation views时,调用此接口
 *@param mapView 地图View
 *@param views 选中的annotation views
 */
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view;


/**
 *取消指定的标注的选中状态,本版暂不支持animate效果
 *@param annotation 指定的标注
 *@param animated 本版暂不支持
 */
- (void)deselectAnnotation:(id <BMKAnnotation>)annotation animated:(BOOL)animated;


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

{

        [mapView deselectAnnotation:view.annotation animated:NO];

}

2015-12-16 17:47:33 yangmeng13930719363 阅读数 3972

MyAnnotation.h文件

#import <Foundation/Foundation.h>
#import <BaiduMapAPI_Map/BMKPointAnnotation.h>

@interface MyAnnotation : BMKPointAnnotation
/**
 *  图标
 */
@property (nonatomic, copy) NSString *icon;

@end

MyAnnotation.m文件

#import "MyAnnotation.h"

@implementation MyAnnotation

@end

MyAnnotationView.h文件

#import <BaiduMapAPI_Map/BMKMapView.h>
#import <BaiduMapAPI_Map/BMKAnnotationView.h>

@interface MyAnnotationView : BMKAnnotationView

/**
 *  创建方法
 *
 *  @param mapView 地图
 *
 *  @return 大头针
 */+ (instancetype)annotationViewWithMap:(BMKMapView *)mapView;
@end

MyAnnotationView.m文件

#import "MyAnnotationView.h"
#import "MyAnnotation.h"

@implementation MyAnnotationView

- (instancetype)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {

    }
    return self;
}

+ (instancetype)annotationViewWithMap:(BMKMapView *)mapView
{
    static NSString *identifier = @"anno";

    // 1.从缓存池中取
    MyAnnotationView *annoView = (HXAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    // 2.如果缓存池中没有, 创建一个新的
    if (annoView == nil) {
        annoView = [[MyAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier];
    }

    return annoView;
}

- (void)setAnnotation:(MyAnnotation *)annotation
{
    [super setAnnotation:annotation];

    //设置图标
    self.image = [UIImage imageNamed:@"icon_green"];
}


@end

之后在控制器文件中,首先要先从服务器获取数据,取到数据后,根据经纬度坐标,也就是一个个的Annotation显示到地图上.

//可以使用,anno是标注
[_mapView addAnnotation:anno];
//或者使用,annos是标注数组
[_mapView addAnnotations:annos];

之后在调用BMKMapViewDelegate的方法;

#pragma mark -BMKMapViewDelegate
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation{
    // 对用户当前的位置的大头针特殊处理
    if ([annotation isKindOfClass:[HXAnnotation class]] == NO) {
        return nil;
    }

    // 创建大头针
    MyAnnotationView *annoView = [MyAnnotationView annotationViewWithMap:mapView];
    // 设置模型
    annoView.annotation = annotation;
    self.anno = annotation;
    //初始化泡泡视图
    DetailsView *detailView = [[[NSBundle mainBundle]loadNibNamed:@"HXDetailsView" owner:nil options:nil] lastObject];
    //显示到paopaoView上
    annoView.paopaoView = [[BMKActionPaopaoView alloc] initWithCustomView:detailView];

    // 返回大头针
    return annoView;
}

才能将annoView显示到地图上.

如果是自定义的paopaoView,BMKMapViewDelegate会有如下方法:

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

我在开发过程中,调用上面的方法并没有作用,所以我在自定义的paopaoView里添加了一个按钮,盖满整个paopaoView,之后添加一个按钮的点击事件,以此来响应泡泡的点击,但是如果有很多的标注,需要最点击的泡泡遍历,否则则不能知道点击的是哪个泡泡.
我根据从服务器获取的数据,服务器返回了有关标注的ID,把这个ID设置为paopaoView上按钮的tag值,然后根据按钮tag值来判断点击的是哪个paopaoView.如下代码:

#pragma mark paopao按钮点击
- (void)detailBtnClick:(UIButton *)button{
    //self.annotations是标注数组
    for (int i = 0; i < self.annotations.count; i++) {
        HXMenDList *menDList = self.annotations[i];
        if (button.tag == [menDList.shopId integerValue]) {
            HXDetailsController *detailsV = [[HXDetailsController alloc] init];
            detailsV.menDList = menDList;
            detailsV.coordinate = self.userLocation.location.coordinate;
            [self.navigationController pushViewController:detailsV animated:YES];
        }
    }
}
2015-09-25 14:03:56 u013513053 阅读数 1532

为什么要把这个拿出来单独写呢,因为标注是地图开发中经常用到的东西,而且需求各种各样,提供的默认标注不足以满足需求。在百度地图的官方文档里面也没有很详细的说明,就把自己的使用心得拿出来记录一下。
首先,要理清楚他们之间的关系。
参考一下百度的类继承关系:
http://wiki.lbsyun.baidu.com/cms/iossdk/doc/v2_8_0/html/hierarchy.html
标注View的继承关系

标注点的继承关系

可以看到,BMKPinAnnotationView继承的BMKAnnotationView,然后BMKActionPaopaoView、BMKAnnotationView和BMKMapView都是继承的UIVIew,属于同一级别。

然后就是标注点,其实就是协议,想要添加标注,就必须实现协议。
这里写图片描述
一般的,我们去创建一个BMKPointAnnotation对象,然后给这个对象的coordinate赋值,coordinate是一个CLLocationCoordinate2D对象,就是坐标点。这样就能在地图上确定位置了。同时还有一个title和subtitle ,设置上这两个属性就会有气泡了,但是气泡的显示还需要在View里面设置的,请继续往先看。
这里引入一段代码:

/**
 * 初始化一个标注
 * 注意:一定要在设置代理之后去添加,不然不会走代理方法,这样就会显示一个默认标注,没有自定义效果了
 */
- (void)initAnnotataion{
    
    BMKPointAnnotation *annotation = [[BMKPointAnnotation alloc]init];
    
    annotation.coordinate = CLLocationCoordinate2DMake(39.915, 116.404);
    annotation.title = @"我在这里ARFAA~~~";
    annotation.subtitle = @"SS";
    
    //在地图上添加Annotation后才会有标注
    [self.mapView addAnnotation:annotation]; 
}

这里可以进行自定义,自定义的只要继承了BMKPointAnnotation就行,然后自己添加一些属性方法之类的,这里就不细说了。

添加完标注,接下来就要走代理方法了。 先看代码

- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
	//这是错误的,放在这里警示一下
    if ([annotation isKindOfClass:[BMKUserLocation class]]) {
        BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
        newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
        newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示
        return newAnnotationView;
    }
    
    //这是正确的写法
    if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
        //设置复用
        CustomAnnotationView *pointAnnotation = (CustomAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"identifier"];
        if (!pointAnnotation)
        {
            pointAnnotation = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"identifier"];
        }
        //动画效果
        //pointAnnotation.animatesDrop = YES;
        //可以拖动
        pointAnnotation.draggable = YES;
        //设置title,选中弹出气泡
        pointAnnotation.canShowCallout = YES;
        //设置自定义标注图标
        pointAnnotation.image = [UIImage imageNamed:@"icon_passenger"];
        
        return pointAnnotation;
    }
    
    return nil;
}

在if里面判断一下是否有此标注,如果有,然后进行下一步。还有一点,如果使用了自定义的标注,最好是判断自定义的类,而不是判断BMKPointAnnotation。因为在之后的话,要使用到这个对象需要强转,父类强转子类对象如果不一致,会崩溃的。
定位其实也是一种标注,在其他地图里是可以这么写的,因为UserLocation会去实现< BMKAnnotation>这个协议,但是百度的没有,猜测可能是在.m中去实现了协议方法。关于如何自定义定位标注,后面再说。
之后我们进行创建View。这个地方我创建了一个自定义的view。自定义的只需要去继承一下BMKPinAnnotationView或者BMKAnnotationView就可以了。之前说过了BMKPinAnnotationView是BMKAnnotationView的子类,继承BMKPinAnnotationView会有默认大头针而已。
我这里自定义的只是为了设置一个自定义泡泡。

- (instancetype)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if (self) {
        self.paopaoView = [[BMKActionPaopaoView alloc]initWithCustomView:self.calloutView];
    }
    return self;
}

- (CustomCalloutView *)calloutView
{
    if (!_calloutView) {
        _calloutView = [[CustomCalloutView alloc] initWithFrame:CGRectMake(0, 0, kCalloutWidth, kCalloutHeight)];
    }
    
    return _calloutView;
}

-(void)setAnnotation:(id<BMKAnnotation>)annotation
{
    [super setAnnotation:annotation];
    
    self.paopaoView = [[BMKActionPaopaoView alloc]initWithCustomView:self.calloutView];
}

这里就是给self.paopaoView赋值而已,没什么特别的。至于CustomCalloutView里面怎么写的,就不详细说明了,其实就是一个View。

这样就完成了自定义标注及气泡。

最后再说一下定位标注。

关于更改定位的样式,百度提供的方式是用mapView设置Param。方法为:
-(void)updateLocationViewWithParam:(BMKLocationViewDisplayParam*)locationViewDisplayParam;
首先创建一个BMKLocationViewDisplayParam对象,设置它的属性。

BMKLocationViewDisplayParam *param = [[BMKLocationViewDisplayParam alloc]init];
    param.locationViewImgName = @"icon_nav_waypoint";
    [_mapView updateLocationViewWithParam:param];

但是要注意,这里的图片一定要在mapapi.bundle资源文件库里,不然无效。

还有一种办法,定位是可以获取到坐标的,完全可以不用系统给出的定位显示,根据定位的坐标自己创建标注,这样就可以更加灵活的去实现显示。

2015-09-04 09:55:39 hczhhm 阅读数 6188

        这篇文章是在我做项目的过程中遇到的一些问题的解决方法,或许并不是最好的解决方法,也可能会出现一些自己不知道的问题,如果大家有更好的方法或发现了我的错误还请指正,因为技术本身就是一个不断交流不断进步的过程。

       废话不多说进入正题:

       百度地图的基本的显示定位相信大家都会使用,这个百度的文档和demo里都有,这里不在累述,突然觉得要加上一句题外话:我配置百度地图的.framework形式的开发包一直没有成功,所以我用的是静态文件的开发包,估计是百度那边的问题。



       第一步声明:

BMKPinAnnotationView * newAnnotationView;
BMKPolyline* polyline;/**<折线*/
NSMutableArray *annoArray;/**<大头针数组*/
NSMutableArray *piAnnoarray;/**<PinAnnotation数组*/
 



      第二步,对数组初始化

piAnnoarray = [[NSMutableArray alloc]init];
annoArray = [[NSMutableArray alloc]init];



       第三步:添加大头针(标注和)折线

-(void)drawAnnotation
{
  
    
        [piAnnoarray removeAllObjects];
        [annoArray removeAllObjects];
       
        float tripArrayCount = [tripArray count];
        
        // 添加折线覆盖物 声明coors 用来放置不确定个数的折点 <span style="font-family: Arial, Helvetica, sans-serif;">tripArray中存放着我的数据</span>

        CLLocationCoordinate2D * coors = (CLLocationCoordinate2D *)malloc(tripArrayCount * sizeof(CLLocationCoordinate2D));
        
        for (int i = 0; i<tripArrayCount; i++) {
            
           BMKPointAnnotation *pointAnnotation = [[BMKPointAnnotation alloc]init];
            CLLocationCoordinate2D coor;
            coor.latitude = [[[tripArray objectAtIndex:i] objectForKey:@"axisY"] floatValue];
            
            coor.longitude = [[[tripArray objectAtIndex:i] objectForKey:@"axisX"] floatValue];
            
            pointAnnotation.coordinate = coor;
            
            if (i == 0) {
    
               /// 设置当前地图的中心点
                [_mapView setCenterCoordinate:pointAnnotation.coordinate animated:YES] ;
             
            }
         
            [annoArray addObject:pointAnnotation];
            [_mapView addAnnotation:pointAnnotation];
            
            
            // 添加折线覆盖物
            coors[i].latitude =  coor.latitude;
            coors[i].longitude = coor.longitude;
            
            
        }
        
        polyline = [BMKPolyline polylineWithCoordinates:coors count:tripArrayCount];
        [_mapView addOverlay:polyline];
    
    }
    
}


// 添加标注的代理方法
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
    
    if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
       newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
        newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
        newAnnotationView.canShowCallout=NO;//不显示气泡 设置这个是为了在不设置title的情况下,标注也能接收到点击事件
        
        newAnnotationView.image = [UIImage imageNamed:@"mapannotation_down"];
        
        //此处加for循环 去找annotation对应的序号标题
        for (int i=0; i<tripArray.count; i++) {
            
            CGFloat lat = [[[tripArray objectAtIndex:i] objectForKey:@"axisY"] floatValue];
            CGFloat lng =  [[[tripArray objectAtIndex:i] objectForKey:@"axisX"] floatValue];
            //通过判断给相对应的标注添加序号标题
            if(annotation.coordinate.latitude == lat && annotation.coordinate.longitude ==  lng )
            {
                if (i==0) {//第一个标注为选中状态,并设置相对应的图片
                    [newAnnotationView setSelected:YES animated:YES];
                    newAnnotationView.image = [UIImage imageNamed:@"mapannotation_up"];
                    
                }
                //给不同的标注添加1,2,3,4,5这样的序号标题
                UILabel *la = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, newAnnotationView.frame.size.width,newAnnotationView.frame.size.height-newAnnotationView.frame.size.height*20/69)];
                la.backgroundColor = [UIColor clearColor];
                la.font = [UIFont systemFontOfSize:12];
                la.textAlignment = NSTextAlignmentCenter;
                la.text = [NSString stringWithFormat:@"%d",i+1];
                la.tag = LABEL_TAG_NUM+i;
                [newAnnotationView addSubview:la];
                
                break;
            }
        }
        //把piAnnoarray添加到数组中
        [piAnnoarray addObject:newAnnotationView];
        return newAnnotationView;
    }
    return nil;
    
}

// Override 折线
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay{
    if ([overlay isKindOfClass:[BMKPolyline class]]){
        BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
        polylineView.strokeColor = [[UIColor purpleColor] colorWithAlphaComponent:1];//颜色
        polylineView.lineWidth = 2.0;//宽度
        
        return polylineView;
    }
    return nil;
}



       第四步,大头针(标注)的点击事件

//当选中一个annotation views时,调用此接口
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view
{
    //坐标
    NSLog(@"选中一个annotation views:%f,%f",view.annotation.coordinate.latitude,view.annotation.coordinate.longitude);
    if ([view.annotation isKindOfClass:[BMKPointAnnotation class]]) {
        //取出piAnnoarray中的每个标注
        for (int i = 0; i<[piAnnoarray count]; i++) {
            
            BMKPinAnnotationView *pinAnnotation = [[BMKPinAnnotationView alloc]init];
            pinAnnotation = [piAnnoarray objectAtIndex:i];
            //判断他的selected状态
            if(pinAnnotation.selected )
            {
                
                pinAnnotation.image = view.image = [UIImage imageNamed:@"mapannotation_up"];
                //重新计算Frame,如果你用的图片大小一样,则不需要重新计算 设置图片一定要放到计算<span style="font-family: Arial, Helvetica, sans-serif;">Frame的前面</span>

                [self SetAonnotionLaFrame:pinAnnotation labelTag:i];
              
                /// 设置当前地图的中心点 把选中的标注作为地图中心点
                [_mapView setCenterCoordinate:pinAnnotation.annotation.coordinate animated:YES] ;
            }
            else{
                
                pinAnnotation.image = [UIImage imageNamed:@"mapannotation_down"];
                
                //重新计算Frame
                [self SetAonnotionLaFrame:pinAnnotation labelTag:i];
                }
            
        }
        

    }
  
}

#pragma -mark 计算大头针上label的frame 
//20和69是我计算图标大小得出的比例
-(void)SetAonnotionLaFrame:(BMKPinAnnotationView *)AnnotationView labelTag:(float)labelTag
{
    //重新计算Frame
    UILabel *label = (UILabel *)[AnnotationView viewWithTag:LABEL_TAG_NUM+labelTag];
    label.frame = CGRectMake(0, 0, AnnotationView.frame.size.width,AnnotationView.frame.size.height-AnnotationView.frame.size.height*20/69);
}



       第五步,删除标注(大头针)和折线 

//删除标注
-(void)removeAnnotion
{
    if (annoArray != nil) {
        [_mapView removeAnnotations:annoArray];
    }
}

//删除折线
-(void)removeOverlay
{
    
    if (polyline != nil) {
        [_mapView removeOverlay:polyline];
    }
}

以上方法也可以删除所有的标注和折线,但有的时候可能会出现无法完全删除的情况,所以推荐使用下面的方法去删除

 

-(void)removeAnnotion
{
    if (annoArray != nil) {
        [_mapView removeAnnotations:_mapView.annotations];
    }
}


-(void)removeOverlay
{
    
    if (polyline != nil) {
        [_mapView removeOverlays:_mapView.overlays];
    }
}


       题外话:因为我做的是有翻页的效果的,就是UIScrollView每翻一页,标注的的选中状态就会发生变化,原来选中的标注变为非选中,在他之前或之后的现在为选中状态,下面是这个效果代码的一个效果,其他的大家以此类推:

                //刚翻过来的一页
                BMKPinAnnotationView *pinAnnotation1 = [[BMKPinAnnotationView alloc]init];
                
                pinAnnotation1= [piAnnoarray objectAtIndex:page-detailsViewNum];
                [pinAnnotation1 setSelected:YES animated:YES];
                
                pinAnnotation1.image = [UIImage imageNamed:@"mapannotation_up"];
                //重新计算Frame
                [self SetAonnotionLaFrame:pinAnnotation1 labelTag:page-detailsViewNum];
                /// 当前地图的中心点
                [_mapView setCenterCoordinate:pinAnnotation1.annotation.coordinate animated:YES] ;
                
                //翻过去的一页
                BMKPinAnnotationView *pinAnnotation2 = [[BMKPinAnnotationView alloc]init];
                pinAnnotation2 = [piAnnoarray objectAtIndex:page-detailsViewNum+1];
                    
                [pinAnnotation2 setSelected:NO animated:YES];
                pinAnnotation2.image = [UIImage imageNamed:@"mapannotation_down"];
                //重新计算Frame
                [self SetAonnotionLaFrame:pinAnnotation2 labelTag:page-detailsViewNum+1];

         

         效果图:

                                                                                                         


         本人技术有限,只能写出项目中遇到的一些问题自己的见解,如有错误还望大家指正。


没有更多推荐了,返回首页