I have a UIView subview called "starfish". It's backing layer is a CAShapeLayer who's path strokes a starfish shape. I want to do hit testing on this shape in my view controller within the enclosed path and not the view's rectangle. This is no problem, I simply call CGPathContainsPoint() on the CAShapeLayer path property in my view controller's touchesBegan and hit testing works.
CGPoint p = [[touches anyObject] locationInView:self.view];
CGPoint q = [self.view convertPoint:p toView:self.starfish];
if (CGPathContainsPoint([(CAShapeLayer*)self.starfish.layer path], NULL, q, true))
NSLog(@"Success");
else
NSLog(@"Fail");
If however the view is animating, moving from A to B, the same hit testing would need to be accessing the CAShapeLayer's path in the presentation layer but I can't seem to be ables to access this.
// Not working during animation
if (CGPathContainsPoint([(CAShapeLayer*)self.starfish.layer.presentationLayer path], NULL, q, true))
NSLog(@"Success");
else
NSLog(@"Fail");
Well I found a solution that works. I create a new CAShapeLayer with the same path and frame (based on the presentation layer) of the CAShapelayer I am testing for in touchesBegan.
CGPoint p = [[touches anyObject] locationInView:self.view];
CGRect rect = [(CAShapeLayer*)self.starfish.layer.presentationLayer frame];
CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = [(CAShapeLayer*)self.starfish.layer path];
shape.frame = rect;
CGPoint q = [self.view.layer convertPoint:p toLayer:shape];
if (CGPathContainsPoint(shape.path, NULL, q, true))
NSLog(@"Success");
else
NSLog(@"Fail");