How can I check if a user tapped near a CGPath?

后端 未结 3 1728
终归单人心
终归单人心 2020-12-05 08:35

Scenario:

I have a set of CGPaths. They are mostly just lines (i.e. not closed shapes). They are drawn on the screen in a UIView\'s draw

相关标签:
3条回答
  • 2020-12-05 09:21

    Well, I figured out an answer. It uses CGPathApply:

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

    Basically it's just my own method for ReplacePathWithStrokedPath, but it only works with lines for right now.

    0 讨论(0)
  • 2020-12-05 09:37

    In Swift

    let area = stroke.copy(strokingWithWidth: 15, lineCap: .round, lineJoin: .round, miterLimit: 1)
    if (area.contains(point)) { ... }
    
    0 讨论(0)
  • 2020-12-05 09:39

    In iOS 5.0 and later, this can be done more simply using CGPathCreateCopyByStrokingPath:

    CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(path, NULL, 15,
        kCGLineCapRound, kCGLineJoinRound, 1);
    BOOL pointIsNearPath = CGPathContainsPoint(strokedPath, NULL, point, NO);
    CGPathRelease(strokedPath);
    
    if (pointIsNearPath) ...
    
    0 讨论(0)
提交回复
热议问题