2014-01-06 70 views
4

在我的應用程序中,我有一個帶有幾個MKGeodesicPolylines的MapView。我希望能夠識別這些線條上的觸摸手勢。 疊加使用補充說:在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!"); 
        ) 

       } 

      } 
     } 


    } 

} 
} 

切換可觸摸區域之間:

更換

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

不要忘記。

+0

這裏的問題是我運行iOS 7和MKPolylineRenderer而不是MKPolylineViews。這使得'convertRect:toView:'不可能。 – freshking

0

我得到它使用WildcardGestureRecognizer和UIGestureRecognizer。看我的帖子的代碼。