场景:
我有一组CGPath,它们大多是线条(即不是闭合的形状)。它们是用UIView的draw方法在屏幕上绘制的。
如何检查用户是否点击了其中一条路径?
以下是我的工作:
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像素以内
发布于 2012-10-20 01:25:28
在iOS 5.0和更高版本中,可以更简单地使用CGPathCreateCopyByStrokingPath来完成此操作
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(path, NULL, 15,
kCGLineCapRound, kCGLineJoinRound, 1);
BOOL pointIsNearPath = CGPathContainsPoint(strokedPath, NULL, point, NO);
CGPathRelease(strokedPath);
if (pointIsNearPath) ...发布于 2009-07-17 22:34:27
好吧,我想出了答案。它使用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;
}
}基本上,这只是我自己的ReplacePathWithStrokedPath方法,但目前它只适用于行。
发布于 2018-11-29 23:04:54
在Swift中
let area = stroke.copy(strokingWithWidth: 15, lineCap: .round, lineJoin: .round, miterLimit: 1)
if (area.contains(point)) { ... }https://stackoverflow.com/questions/1143704
复制相似问题