2009-07-17 4 views
9

시나리오 :사용자가 CGPath 근처에서 탭했는지 어떻게 확인할 수 있습니까?

나는 CGPath 세트를 가지고 있습니다. 그것들은 대체로 단순한 선들입니다 (즉, 닫힌 모양이 아닙니다). 그들은 UIView의 그림 그리기 방법으로 화면에 그려집니다.

사용자가 경로 중 하나를 탭했는지 어떻게 확인할 수 있습니까?

는 여기에 내가 작업 한 내용은 다음과 같습니다

UIGraphincsBeginImageContext(CGPathGetBoundingBox(path)); 
CGContextRef g = UIGraphicsGetCurrentContext(); 
CGContextAddPath(g,path); 
CGContextSetLineWidth(g,15); 
CGContextReplacePathWithStrokedPath(g); 
CGPath clickArea = CGContextCopyPath(g); //Not documented 
UIGraphicsEndImageContext(); 

그래서 나는 그것이 내가 필요로하는 기능을 가지고 있기 때문에, 이미지 컨텍스트를 만드는 일을 해요. 그런 다음 컨텍스트에 경로를 추가하고 선 너비를 15로 설정합니다.이 지점에서 경로를 스트로킹하면 클릭 수를 찾기 위해 내부에서 확인할 수있는 클릭 영역이 만들어집니다. 그래서 나는 그 문구를 쓰다듬어 진 경로로 바꾸고 그 경로를 다시 다른 CGPath로 복사하는 방법으로 그 선명한 길을 얻는다. 나중에, 내가 확인할 수 있습니다

if (CGPathContainsPoint(clickArea,NULL,point,NO)) { ... 

를 모든 것이 잘 좋은 일을하지만, CGContextCopyPath는 문서화되지 않은 것으로, 명백한 이유를 위해 사용하는 나쁜 생각처럼 보였다. 이 목적을 위해서 CGContext을 만드는 것에 대한 약간의 끈적 함이 있습니다.

아무도 아이디어가 있습니까? 사용자가 CGPath에있는 모든 지역 (이 경우 15 픽셀 이내)을 탭했는지 어떻게 확인합니까?

답변

18

이상이 CGPathCreateCopyByStrokingPath를 사용하여 더 간단하게 수행 할 수 있습니다

CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(path, NULL, 15, 
    kCGLineCapRound, kCGLineJoinRound, 1); 
BOOL pointIsNearPath = CGPathContainsPoint(strokedPath, NULL, point, NO); 
CGPathRelease(strokedPath); 

if (pointIsNearPath) ... 
+2

Swift 3.0에서 :'path.copy (strokingWithWidth : CGFloat ...)' – buildsucceeded

2

글쎄, 나는 대답을 알아 냈다.

clickArea = CGPathCreateMutable(); 
CGPathApply(path,clickArea,&createClickArea); 

void createClickArea (void *info, const CGPathElement *elem) { 
    CGPathElementType type = elem->type; 
    CGMutablePathRef path = (CGMutablePathRef)info; 
    static CGPoint last; 
    static CGPoint subpathStart; 
    switch (type) { 
    case kCGPathElementAddCurveToPoint: 
    case kCGPathElementAddQuadCurveToPoint: 
     break; 
    case kCGPathElmentCloseSubpath: 
    case kCGPathElementMoveToPoint: { 
     CGPoint p = type == kCGPathElementAddLineToPoint ? elem->points[0] : subpathStart; 
     if (CGPointEqualToPoint(p,last)) { 
     return; 
     } 
     CGFloat rad = atan2(p.y - last.y, p.x - last.x); 
     CGFloat xOff = CLICK_DIST * cos(rad); 
     CGFloat yOff = CLICK_DIST * sin(rad); 
     CGPoint a = CGPointMake(last.x - xOff, last.y - yOff); 
     CGPoint b = CGPointMake(p.x + xOff, p.y + yOff); 
     rad += M_PI_2; 
     xOff = CLICK_DIST * cos(rad); 
     yOff = CLICK_DIST * sin(rad); 
     CGPathMoveToPoint(path, NULL, a.x - xOff, a.y - yOff); 
     CGPathAddLineToPoint(path, NULL, a.x + xOff, a.y + yOff); 
     CGPathAddLineToPoint(path, NULL, b.x + xOff, b.y + yOff); 
     CGPathAddLineToPoint(path, NULL, b.x - xOff, b.y - yOff); 
     CGPathCloseSubpath(path); 
     last = p; 
     break; } 
    case kCGPathElementMoveToPoint: 
     subpathStart = last = elem->points[0]; 
     break; 
    } 
} 

은 기본적으로는 ReplacePathWithStrokedPath 단지 내 자신의 방법이지만, 그것은 단지 지금 라인과 함께 작동 : 그것은 CGPathApply를 사용합니다. 아이폰 OS 5.0에서

+0

감사에게 많은이를 게시! 나 자신은 그것에 대해 단서를 가지지 않을 것이다. 비록 대답이 정상적으로 작동했지만,이 기능은 유연성을 제공하기 때문에 기본적으로 나를 구해주었습니다. 나는 경로 요소를 다르게 취급 할 수 있습니다. 정확히 필요한 것입니다. 다시 한 번 감사드립니다! – user1244109

관련 문제