9

我有一个使用MKCircles 显示某些用户操作的半径信息的地图视图。

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

有任何想法吗?

这是我当前的代码,它会MKCircle在触摸地图的任何部分时关闭:

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

2 回答 2

7

在该deactivateAllRadars方法中,您可以使用hitTest:withEvent:来判断一个是否MKAnnotationView已被点击。

我如何在 MapView 上点击然后将其传递给默认手势识别器中显示了一个示例?(这是第二个代码示例)。

如果已点击注释,这将使您避免删除圆圈。

如果尚未点击注释,则可以MKCircle通过获取触摸的坐标来检查是否被点击(请参阅如何在 MKMapView 上捕获点击手势)并查看从触摸到圆心的距离是否更大比它的半径。

请注意,deactivateAllRadars应该将其更改为,deactivateAllRadars:(UITapGestureRecognizer *)tgr因为它需要来自相关手势识别器的信息。还要确保在您 alloc+init 的方法选择器的末尾添加一个冒号tap

例如:

-(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...
            }
        }
    }
}
于 2012-11-21T20:06:54.430 回答
3

这是我的Swift 2.1兼容版本:

func didTapOnMap(recognizer: UITapGestureRecognizer) {
    let tapLocation = recognizer.locationInView(self)
    if let subview = self.hitTest(tapLocation, withEvent: nil) {
        if subview.isKindOfClass(NSClassFromString("MKNewAnnotationContainerView")!) {
            print("Tapped out")
        }
    }
}

MKNewAnnotationContainerView是一个私有内部类,所以你不能像这样直接比较:

if subview is MKNewAnnotationContainerView {
}
于 2016-03-21T13:57:00.033 回答