3

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

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

现在我想检测单一颜色/图层上方的点击。我尝试这种方式:

- (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类,其中彩虹正在drawRect使用UIBezierPaths. 然后我按照http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html中的“在路径上进行命中检测”部分进行操作, 在这种情况下,问题是传递给方法的路径变量。我尝试将UIBezierPath传递的路径与路径进行比较,RainbowView但没有结果。

我可以尝试创建曲线而不是路径。在这种情况下,可能没有图形的填充部分,并且触摸区域仅限于笔划。但是,我怎样才能识别曲线上的触摸呢?

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

4

1 回答 1

2

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

如果您的路径已填满,则应改为使用CGPathContainsPoint()来确定水龙头是否在路径内。如果您的路径没有被填充而是被抚摸,我建议您参考Ole Begemann 关于 CGPath Hit Testing 的文章

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

于 2013-02-03T15:55:56.710 回答