In my app I have a MapView with a few MKGeodesicPolylines. I want to be able to recognize touch gestures on these lines. The overlay are added using:
[_mapView addOverlay:polyline];
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
    if ([overlay class] == [MKGeodesicPolyline class])
    {
        MKPolylineRenderer *renderer = [[[MKPolylineRenderer alloc] initWithPolyline:overlay] autorelease];
        renderer.lineWidth = 4.0;
        renderer.strokeColor = [UIColor blackColor];
        return renderer;
    }
 return nil;
}
I have tried WildcardGestureRecognizer which should fit my purpose. Here is the code I am using:
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        .... MapView init ....
        WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
        tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
            UITouch *touch = [touches anyObject];
            CGPoint point = [touch locationInView:_mapView];
            CLLocationCoordinate2D coord = [_mapView convertPoint:point toCoordinateFromView:self.mapView];
            MKMapPoint mapPoint = MKMapPointForCoordinate(coord);
            for (id overlay in _mapView.overlays)
            {
                if ([overlay isKindOfClass:[MKGeodesicPolyline class]])
                {
                    MKGeodesicPolyline *poly = (MKGeodesicPolyline*) overlay;
                    id view = [_mapView viewForOverlay:poly];
                    NSLog(@"view class: %@",[view class]);
                    if ([view isKindOfClass:[MKPolylineRenderer class]])
                    {
                        MKPolylineRenderer *polyView = (MKPolylineRenderer*) view;
                        CGPoint polygonViewPoint = [polyView pointForMapPoint:mapPoint];
                        BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO);
                        if (mapCoordinateIsInPolygon) {
                            NSLog(@"hit!");
                        } else {
                            NSLog(@"miss!");
                        }
                    }
                }
            }
        };
        [_mapView addGestureRecognizer:tapInterceptor];
    }
    return self;
}
The problem is the point of the code above where the first Log gets called. The class always seems to return null. Log output:
2014-01-06 13:50:41.106 App[11826:60b] view class: (null)
I hope somebody could point me into the right direction. Thanks a lot in advance!
WORKING CODE:
I got it working for me. Hope it helps somebody else:
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        .... MapView init ....
        WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
        tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
            CGPoint point = [tapInterceptor locationInView:_mapView];
            CLLocationCoordinate2D coord = [_mapView convertPoint:point toCoordinateFromView:self.mapView];
            MKMapPoint mapPoint = MKMapPointForCoordinate(coord);
            for (id overlay in _mapView.overlays)
            {
                if ([overlay isKindOfClass:[MKGeodesicPolyline class]])
                {
                    MKGeodesicPolyline *poly = (MKGeodesicPolyline*) overlay;
                    id view = [_mapView viewForOverlay:poly];
                    NSLog(@"view class: %@",[view class]);
                    if ([view isKindOfClass:[MKPolylineRenderer class]])
                    {
                        MKPolylineRenderer *polyView = (MKPolylineRenderer*) view;
                        [polyView invalidatePath];
                        CGPoint polygonViewPoint = [polyView pointForMapPoint:mapPoint];
                        BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO);
                            if (mapCoordinateIsInPolygon)
                            {
                                NSLog(@"hit!");
                            } else {
                                NSLog(@"miss!");
                            }
                    }
                }
            }
        };
        [_mapView addGestureRecognizer:tapInterceptor];
    }
    return self;
}
ALTERNATIVE:
Add UITapGestureRecognizer:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
[_mapView addGestureRecognizer:recognizer];
[recognizer release];
Handle gesture:
- (void)handleGesture:(UIGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded)
{
    for (int i=0; i<recognizer.numberOfTouches; i++)
    {
        //CGPoint point = [recognizer locationInView:_mapView];
        CGPoint point = [recognizer locationOfTouch:i inView:_mapView];
        CLLocationCoordinate2D coord = [_mapView convertPoint:point toCoordinateFromView:self.mapView];
        MKMapPoint mapPoint = MKMapPointForCoordinate(coord);
        for (id overlay in _mapView.overlays)
        {
            if ([overlay isKindOfClass:[MKGeodesicPolyline class]])
            {
                MKGeodesicPolyline *poly = (MKGeodesicPolyline*) overlay;
                id view = [_mapView rendererForOverlay:poly];
                if ([view isKindOfClass:[MKPolylineRenderer class]] && [[poly title] isEqualToString:@"fullRouteAbove"])
                {
                    MKPolylineRenderer *polyView = (MKPolylineRenderer*) view;
                    [polyView invalidatePath];
                    CGPoint polygonViewPoint = [polyView pointForMapPoint:mapPoint];
                    NSLog(@"polyView: %@",polyView);
                    BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO);
                    if (mapCoordinateIsInPolygon)
                    {
                        NSLog(@"hit!");
                    }else{
                        NSLog(@"miss!");
                    )
                }
            }
        }
    }
}
}
SWITCHING BETWEEN TOUCHABLE AREAS:
Replace
BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO);
with
BOOL mapCoordinateIsInPolygon = CGRectContainsPoint(CGPathGetBoundingBox(polyView.path), polygonViewPoint);
or
BOOL mapCoordinateIsInPolygon = CGRectContainsPoint(CGPathGetPathBoundingBox(polyView.path), polygonViewPoint);
 
     
    