IOS CALayer and TapGestureRecognizer

I am developing an iOS 6.1 app for iPad. I have a problem with CALayer

and TapGestureRecognizer

.

I have 7 CALayers

rainbow shapers (each layer is a color). Each layer is built using the CAShapeLayer

generated from CGMutablePathRef

. Everything works fine. All the layers are drawn on the screen and I can see a beautiful rainbow.

Now I want to detect click over one color / layer. I am trying like this:

- (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!");
}

      

I don't understand why this code won't work! I already have hitTest:

other threads here: all suggest a hitTest:

method for solving similar problems. But in my case, I cannot get the desired result. Can anyone help me? Thank!!

EDIT:

Here is the code for creating paths and layers:

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

      

This was my first approach to the problem. And the touch didn't work.

I also tried to create a class RainbowView

that draws the rainbow in a method drawRect

using UIBezierPaths

. Then I follow the section on "Path Hit Detection" at http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html In this case the problem was the path variable being passed to the method ... I am trying to compare UIBezierPath

passed to paths in RainbowView

but RainbowView

.

I could try to create curves instead of paths. In this case, there may not be a filled part of the shape, and the area of ​​contact is limited by a stroke. But then how can I recognize tangency on a curve?

I am so confused about all these things !!! : D

+3


source to share


1 answer


The problem you are running into is that you are checking again the borders / boundaries of the layer when testing the hit and are not repeating the path of the shape layer.

If your paths are full, you should instead use CGPathContainsPoint()

to determine if a crane was in transit. If your paths are not filled in and instead stroked, I refer you to Ole Begemann's article on testing CGPath Hit .



To make your code cleaner you can do hit testing in your own subclass. Also, if the layer is not animated when testing beats, it doesn't make sense using a presentation layer.

+2


source







All Articles