2015-02-10 49 views
1

我有一個覆蓋圓的地圖,它總是從CGPathContainsPoint方法返回false。我是否傳入了錯誤的tapPoint值?檢測點擊地圖圈覆蓋總是返回false

func didTapMap(gestureRecognizer: UIGestureRecognizer) { 
    let tapPoint: CGPoint = gestureRecognizer.locationInView(map) 
    NSLog("%@,%@",tapPoint.x, tapPoint.y) 

    for overlay in self.map.overlays{ 
     if (overlay.isKindOfClass(MKCircle)) 
     { 
      let circle = overlay as MKCircle 
      let circleRenderer:MKCircleRenderer = map.rendererForOverlay(circle) as MKCircleRenderer 
      circleRenderer.invalidatePath() 
      let mapCoordinateIsInCircle = CGPathContainsPoint(circleRenderer.path, nil, tapPoint, false) 

      if (mapCoordinateIsInCircle == true) 
      { 
       NSLog("tapped in circle"); 
       break 
      } 
     } 
    } 

} 

回答

3

是的,將錯誤的分接點值傳遞給CGPathContainsPoint

覆蓋渲染器的path中的值不在屏幕CGPoint單位中。
path包含與渲染器自己的繪圖上下文不同的屏幕值。

您需要先將屏幕CGPoint中的點觸點轉換爲渲染器繪圖上下文中的點。

MKOverlayRenderer(基類的MKCircleRenderer)具有方法pointForMapPoint:它可以幫助,但它需要一個MKMapPoint(未屏幕CGPoint)。

因此,您需要將屏幕CGPoint轉換爲MKMapPoint,然後最終轉換爲呈現器上下文中的某個點。

從屏幕CGPoint轉換爲MKMapPoint,您需要先使用它使用MKMapPointForCoordinate功能轉換爲CLLocationCoordinate2D地圖視圖的convertPoint:toCoordinateFromView:然後到MKMapPoint

實施例:

func didTapMap(gestureRecognizer: UIGestureRecognizer) { 
    let tapPoint: CGPoint = gestureRecognizer.locationInView(map) 
    NSLog("tapPoint = %f,%f",tapPoint.x, tapPoint.y) 

    //convert screen CGPoint tapPoint to CLLocationCoordinate2D... 
    let tapCoordinate = map.convertPoint(tapPoint, toCoordinateFromView: map) 

    //convert CLLocationCoordinate2D tapCoordinate to MKMapPoint... 
    let tapMapPoint = MKMapPointForCoordinate(tapCoordinate) 

    for overlay in self.map.overlays{ 
     if (overlay.isKindOfClass(MKCircle)) 
     { 
      let circle = overlay as MKCircle 
      let circleRenderer:MKCircleRenderer = map.rendererForOverlay(circle) as MKCircleRenderer 

      //convert MKMapPoint tapMapPoint to point in renderer's context... 
      let tapRendererPoint = circleRenderer.pointForMapPoint(tapMapPoint) 

      circleRenderer.invalidatePath() 

      let mapCoordinateIsInCircle = CGPathContainsPoint(circleRenderer.path, nil, tapRendererPoint, false) 

      if (mapCoordinateIsInCircle == true) 
      { 
       NSLog("tapped in circle"); 
       break 
      } 
     } 
    } 
} 


順便說一句,用圓圈,更簡單的方法來檢測在其內部抽頭是從圓的中心計算的抽頭點的距離。如果分接點距離小於或等於圓的半徑,那麼它是圓內的一個水龍頭。

這樣,您不需要獲取圓的渲染器,其路徑或CGPathContainsPoint。

例子:

func didTapMap(gestureRecognizer: UIGestureRecognizer) { 
    let tapPoint: CGPoint = gestureRecognizer.locationInView(map) 
    NSLog("tapPoint = %f,%f",tapPoint.x, tapPoint.y) 

    let tapCoordinate = map.convertPoint(tapPoint, toCoordinateFromView: map) 

    let tapMapPoint = MKMapPointForCoordinate(tapCoordinate) 

    for overlay in self.map.overlays{ 
     if (overlay.isKindOfClass(MKCircle)) 
     { 
      let circle = overlay as MKCircle 

      let circleCenterMapPoint = MKMapPointForCoordinate(circle.coordinate) 

      let distanceFromCircleCenter = MKMetersBetweenMapPoints(circleCenterMapPoint, tapMapPoint) 

      if distanceFromCircleCenter <= circle.radius { 
       NSLog("tapped in circle"); 
       break 
      } 
     } 
    }  
} 
+0

我覺得你的建議「與圈子,一個簡單的方法來檢測水龍頭裏面他們是從圓心計算抽頭點的距離」的相關點。我標記了它,因爲這解決了我在Objective C中的問題。 – Greg 2016-02-11 22:16:57