2013-02-03 39 views
3

我正在为iOS iPad 6.1开发应用程序。 我对CALayer和TapGestureRecognizer有问题。iOS CALayer和TapGestureRecognizer

我有7名CALayers形成彩虹(每层都是一种颜色)。 每个图层都是使用从CGMutablePathRef生成的CAShapeLayer构建的。一切正常。所有的图层都在屏幕上绘制,我可以看到美丽的彩虹。

现在我想检测单个颜色/图层上方的水龙头。我试试这种方式:

- (void)tap:(UITapGestureRecognizer*)recognizer 
{ 
    //I've had the tapGestureRecognizer to rainbowView (that is an UIView) in viewDidLoad 
    CGLayer* tappedLayer = [rainbowView.layer.presentationlayer hitTest:[recognizer locationInView:rainbowView]; 

    if (tappedLayer == purpleLayer) //for example 
     NSLog(@"PURPLE!"); 
} 

我不明白为什么这段代码不起作用!我已经在这里红色的其他主题:所有建议的“hitTest:”方法来解决这样的问题。但在我的情况下,我无法获得理想的结果。 任何人都可以帮助我吗?谢谢!!

编辑:

下面是创建的路径和层代码:

- (void)viewDidLoad 
{ 
    //Other layers 
    ... 
    ... 
    //Purple Arc 
    purplePath = CGPathCreateMutable(); 
    CGPathMoveToPoint(purplePath, NULL, 150, 400); 
    CGPathAddCurveToPoint(purplePath, NULL, 150, 162, 550, 162, 550, 400); 
    purpletrack = [CAShapeLayer layer]; 
    purpletrack.path = purplePath; 
    purpletrack.strokeColor = [UIColor colorWithRed:134.0/255.0f green:50.0/255.0f blue:140.0/255.0f alpha:1.0].CGColor; 
    purpletrack.fillColor = nil; 
    purpletrack.lineWidth = 25.0; 
    [rainbowView.layer insertSublayer:purpletrack above:bluetrack]; 
} 

这是我的第一个解决问题的方法。触摸不起作用。

我也尝试创建一个RainbowView类,其中彩虹使用UIBezierPaths在drawRect方法中绘制。 然后我按照http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html 中的“在路径上执行命中检测”部分在这种情况下,问题是传递给该方法的路径变量。我尝试比较通过RainbowView中的路径传递的UIBezierPath,但没有结果。

我可以尝试创建曲线而不是路径。在这种情况下,可能没有图的填充部分,并且触摸区域限于中风。但是,我怎么能认识到曲线上的触摸?

我对所有这些东西很困惑! :D

回答

2

您面临的问题是您在点击测试时再次检查图层的边框/边界,而不是再次检查形状图层的路径。

如果您的路径已满,您应改为使用CGPathContainsPoint()来确定水龙头是否位于路径内。如果你的路径没有填充,而是抚摸着我,你可以参考Ole Begemann's article about CGPath Hit Testing

为了让您的代码更清洁,您可以在自己的子类中进行命中测试。另外,除非在命中测试时该图层为动画,否则使用presentationLayer是没有意义的。

+0

感谢您的提示!现在我正在阅读Ole Begemann的文章,以更好地了解这种情况。再次感谢你。 – nicopasso

+1

不幸的是CGPathContainsPoint()和Ole Begemann的方法都不适用于我。事实可能是我的层是一个在另一个之上。而水龙头将无法工作,因为每层的“填充部分”始终存在!也许我只能用CGContextAddArcToPoint或类似的东西来创建曲线。但我不知道如何在单一曲线上获得点击。 – nicopasso

+0

在这种情况下,问题需要关于如何构建路径和图层的信息。 –