如何添加触摸手势来映射但忽略引脚和注释上的触摸? [英] How to add touch gesture to map but ignore touches on pins and annotations?

查看:133
本文介绍了如何添加触摸手势来映射但忽略引脚和注释上的触摸?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 MKCircle 的mapview来显示某些用户操作的半径信息。



我是什么想要做的是,允许用户在触摸地图时解除 MKCircle 。但是,如果用户触摸任何其他引脚或 MKCircle 本身,我希望 MKCircle 不要忽略。



任何想法?



这是我当前的代码,它解除了 MKCircle 当触摸地图的任何部分时:

  UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:自我行动:@selector(deactivateAllRadars)]; 
[tap setCancelsTouchesInView:NO];
[_mapView addGestureRecognizer:tap];


解决方案

deactivateAllRadars 方法,您可以使用 hitTest:withEvent:判断是否已点击 MKAnnotationView



这方面的一个例子显示在我怎样才能点击MapView然后将其传递给默认手势识别器?(这是第二个代码示例)。 / p>

如果点击了注释,这可以避免删除圈子。



如果尚未点击注释,则可以通过获取触摸坐标来检查是否点击了 MKCircle (请参阅如何在MKMapView上捕捉Tap手势以获取示例)并查看从触摸到c的距离ircle的中心大于其半径。



请注意, deactivateAllRadars 应更改为 deactivateAllRadars:(UITapGestureRecognizer *)tgr 因为它需要来自相关手势识别器的信息。另外一定要在方法选择器的末尾添加一个冒号,你可以在其中分配+ init 点击



For例如:

   - (void)deactivateAllRadars:(UITapGestureRecognizer *)tgr 
{
CGPoint p = [ tgr locationInView:mapView];

UIView * v = [mapView hitTest:p withEvent:nil];

id< MKAnnotation> ann = nil;

if([v isKindOfClass:[MKAnnotationView class]])
{
//点击了注释视图,选择它...
ann =((MKAnnotationView *)v)的.annotation;
[mapView selectAnnotation:ann animated:YES];
}
其他
{
//没有点击注释视图,如果选择了某个ann则取消选择...
if(mapView.selectedAnnotations.count!= 0 )
{
ann = [mapView.selectedAnnotations objectAtIndex:0];
[mapView deselectAnnotation:ann animated:YES];
}


//如果没有点击则删除圆圈叠加...
if(mapView.overlays.count> 0)
{
CGPoint touchPoint = [tgr locationInView:mapView];

CLLocationCoordinate2D touchMapCoordinate
= [mapView convertPoint:touchPoint toCoordinateFromView:mapView];

CLLocation * touchLocation = [[CLLocation alloc]
initWithLatitude:touchMapCoordinate.latitude
经度:touchMapCoordinate.longitude];

CLLocation * circleLocation = [[CLLocation alloc]
initWithLatitude:circleCenterLatitude
经度:circleCenterLongitude];

CLLocationDistance distFromCircleCenter
= [touchLocation distanceFromLocation:circleLocation];

if(distFromCircleCenter> circleRadius)
{
//点击圈子外面,调用removeOverlay ...
}
}
}
}


I have a mapview that uses MKCircles to display radius information for certain user actions.

What I want to do, is allow the user to dismiss the MKCircle when they touch the map. However, I would like the MKCircle to NOT dismiss should the user touch any of the other pins or the MKCircle itself.

Any ideas?

Here is my current code, which dismisses the MKCircle when any part of the map is touched:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(deactivateAllRadars)];
[tap setCancelsTouchesInView:NO];
[_mapView addGestureRecognizer:tap];

解决方案

In the deactivateAllRadars method, you can use hitTest:withEvent: to tell whether an MKAnnotationView has been tapped or not.

An example of this is shown in How can I catch tap on MapView and then pass it to default gesture recognizers? (it's the second code sample).

This will let you avoid removing the circle if an annotation has been tapped.

If an annotation has not been tapped, you can then check if an MKCircle was tapped by getting the coordinates of the touch (see How to capture Tap gesture on MKMapView for an example) and seeing if the distance from the touch to the circle's center is greater than its radius.

Note that the deactivateAllRadars should be changed to deactivateAllRadars:(UITapGestureRecognizer *)tgr because it will need information from the associated gesture recognizer. Also be sure to add a colon at the end of the method's selector where you alloc+init tap.

For example:

-(void)deactivateAllRadars:(UITapGestureRecognizer *)tgr
{
    CGPoint p = [tgr locationInView:mapView];

    UIView *v = [mapView hitTest:p withEvent:nil];

    id<MKAnnotation> ann = nil;

    if ([v isKindOfClass:[MKAnnotationView class]])
    {
        //annotation view was tapped, select it...
        ann = ((MKAnnotationView *)v).annotation;
        [mapView selectAnnotation:ann animated:YES];
    }
    else
    {
        //annotation view was not tapped, deselect if some ann is selected...
        if (mapView.selectedAnnotations.count != 0)
        {
            ann = [mapView.selectedAnnotations objectAtIndex:0];
            [mapView deselectAnnotation:ann animated:YES];
        }


        //remove circle overlay if it was not tapped...        
        if (mapView.overlays.count > 0)
        {
            CGPoint touchPoint = [tgr locationInView:mapView];

            CLLocationCoordinate2D touchMapCoordinate 
              = [mapView convertPoint:touchPoint toCoordinateFromView:mapView];

            CLLocation *touchLocation = [[CLLocation alloc] 
              initWithLatitude:touchMapCoordinate.latitude 
              longitude:touchMapCoordinate.longitude];

            CLLocation *circleLocation = [[CLLocation alloc] 
              initWithLatitude:circleCenterLatitude 
              longitude:circleCenterLongitude];

            CLLocationDistance distFromCircleCenter 
              = [touchLocation distanceFromLocation:circleLocation];

            if (distFromCircleCenter > circleRadius)
            {
                //tap was outside the circle, call removeOverlay...
            }
        }
    }
}

这篇关于如何添加触摸手势来映射但忽略引脚和注释上的触摸?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆