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
source to share
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.
source to share