检测CAShapeLayer上的触摸(线)

时间:2013-03-15 00:33:33

标签: core-animation

使用我在互联网上看到的标准代码,我无法检测到单个`CAShapeLayer的触摸。

CGPoint p = [[touches anyObject] locationInView:self.view];

    CGPathRef path = ((CAShapeLayer *)[lettersArray objectAtIndex:1]).path;

    if(CGPathContainsPoint(path, nil, p, NO))
    {
        ((CAShapeLayer *)[lettersArray objectAtIndex:0]).position = p;
        NSLog(@"Touched");
    }

我是否需要至少有一些区域而不仅仅是一个片段?

3 个答案:

答案 0 :(得分:1)

Buddy试试这个代码对我有用

CGPathRef originalPath = shapeView.path;  //The single-line path

//Use the values you use to draw the path onscreen,
//or use a width representing how far the user can touch
//for it to be recognized by the path.
//For example, for an error tolerance of 4px, use a width of 8px.
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(originalPath, NULL, path.lineWidth, path.lineCapStyle, path.lineJoinStyle, path.miterLimit);
BOOL pathContainsPoint = CGPathContainsPoint(strokedPath, NULL, touchLocation, NO);

NSLog(pathContainsPoint ? @"Yes" : @"No");

答案 1 :(得分:0)

是的,您的路径需要有一些CGPathContainsPoint区域来测试其中的一个点。您可能想要做的是find the distance from the point to the line并测试它是否在某个阈值内。

请注意,该文章中的公式为您提供了到的距离,而不是;如果线上最近的点超出了线段的边界,则还需要计算从点到线段终点的距离。

答案 2 :(得分:0)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

for (UITouch *touch in touches) {
    CGPoint touchLocation = [touch locationInView:self.view];
    for (id sublayer in self.view.layer.sublayers) {
        BOOL touchInLayer = NO;
        if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
            CAShapeLayer *shapeLayer = sublayer;
            if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
                // This touch is in this shape layer
                touchInLayer = YES;
            }
        } else {
            CALayer *layer = sublayer;
            if (CGRectContainsPoint(layer.frame, touchLocation)) {
                // Touch is in this rectangular layer
                touchInLayer = YES;
            }
        }
    }
}

}