2014-01-06 3 views
4

В моем приложении у меня есть MapView с несколькими MKGeodesicPolylines. Я хочу уметь распознавать жесты касания на этих линиях. покрышка добавляются с помощью:Обнаружение жестов касания на MKPolyline

[_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; 
} 

Я попытался WildcardGestureRecognizer, который должен соответствовать своей цели. Вот код, который я использую:

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

Проблема заключается в том, что код выше, где вызывается первый журнал. Кажется, что класс возвращает null. Вход выход:

2014-01-06 13:50:41.106 App[11826:60b] view class: (null)

Я надеюсь, что кто-то может мне точку в правильном направлении. Большое спасибо!

РАБОТА КОД:

Я получил это работает для меня. Надеюсь, что это помогает кто-то еще:

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

АЛЬТЕРНАТИВА:

Добавить UITapGestureRecognizer:

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; 
[_mapView addGestureRecognizer:recognizer]; 
[recognizer release]; 

Ручка жест:

- (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!"); 
        ) 

       } 

      } 
     } 


    } 

} 
} 

ПЕРЕКЛЮЧЕНИЕ МЕЖДУ Touchable РАЙОНОВ:

Заменить

BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO); 

с

BOOL mapCoordinateIsInPolygon = CGRectContainsPoint(CGPathGetBoundingBox(polyView.path), polygonViewPoint); 

или

BOOL mapCoordinateIsInPolygon = CGRectContainsPoint(CGPathGetPathBoundingBox(polyView.path), polygonViewPoint); 
+0

Возможно, потому что код вызывает 'viewForOverlay' вместо' rendererForOverlay'. Вы также можете столкнуться с [этой проблемой] (http://stackoverflow.com/questions/19014926/detecting-a-point-in-a-mkpolygon-broke-with-ios7-cgpathcontainspoint/19018733#19018733). – Anna

ответ

3

Я думаю, что вам это нужно:

Добавить NSMutableArray называется arrPolylineViews к вашему классу.

Затем добавьте tapGestureRecognizer к вашему MAPview:

UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] init]; 
gr.numberOfTapsRequired = 1; 
gr.numberOfTouchesRequired = 1; 
gr.delegate = self; 
[gr addTarget:self action:@selector(didTap:)]; 
[myMapView addGestureRecognizer:gr]; 

В didTap:

- (void)didTap:(UITapGestureRecognizer *)gr 
{ 
    if (gr.state == UIGestureRecognizerStateEnded) 
    { 
     // convert the touch point to a CLLocationCoordinate & geocode 
     CGPoint touchPoint = [gr locationInView:myMapView]; 
     MKPolylineView *touchedPolyLineView = [self polylineTapped:touchPoint]; 
     if (touchedPolyLineView) 
     { 
      //touched a polyLineView 
     } 
    } 
} 

Тогда:

- (MKOverlayView*)mapView:(MKMapView*)theMapView viewForOverlay:(id <MKOverlay>)overlay 
{ 
    if([overlay isKindOfClass:[MKPolyline class]]){ 
     //create your polyLineView 
     [arrPolylineViews addObject:polyLineView]; 
    } 
} 

Затем добавьте этот метод:

- (MKPolylineView *)polylineTapped:(CGPoint)point 
{ 
    // Check if the overlay got tapped 
    for (MKPolylineView *polyView in arrPolylineViews) 
    { 
     // Get view frame rect in the mapView's coordinate system 
     CGRect viewFrameInMapView = [polyView.superview convertRect:polyView.frame toView:myMapView]; 

     // Check if the touch is within the view bounds 
     if (CGRectContainsPoint(viewFrameInMapView, point)) 
     { 
      return polyView; 
     } 
    } 
    return nil; 
} 

Не забудьте -

[arrPolylineViews removeAllObjects]; 

перед добавлением нового списка точек на карте.

+0

Проблема здесь в том, что я запускаю iOS 7 и MKPolylineRenderer, а не MKPolylineViews. Это делает невозможным «convertRect: toView:». – freshking

0

Я получил его работу с использованием WildcardGestureRecognizer и UIGestureRecognizer. См. Мой пост для кода.

Смежные вопросы