CALayer -hitTest: not respecting containsPoint: overload
Question
Back again and have a different question with the same function that I posted before:
- (AIEnemyUnit *) hitTestForEnemyUnit:(CGPoint)where {
CALayer * layer = [self hitTest:where];
while (layer) {
if ([layer isKindOfClass:[AIEnemyUnit class]]) {
return (AIEnemyUnit *)layer;
} else {
layer = layer.superlayer;
}
}
return nil;
}
I have a bomb that the user drags on top of the enemy so that it is displayed directly above the AIEnemyUnit. For this bomb I implemented the CALayer -containsPoint:
to return NO during a drag to allow -hitTest: to pass through the layer. Basically this type of hit testing was working fine with these "pass-through" layers as long as I only used CGImageRef contexts. However once I started implementing sublayers for additional effects on the bomb, -hitTest:
immediately broke. It was obvious, the new layers were capturing the -hitTest:
. I tried implementing the same technique by overloading -containsPoint:
for these layers, but it was still returning the bomb's generic CALayer subclass instead of passing through.
Is there a better way?
Solution
Maybe the "where" point is not relative to your "self" layer. You need to convert these points between the layers coordinate systems using:
– convertPoint:fromLayer: or – convertPoint:toLayer:
OTHER TIPS
I resolved this by putting everything on a second "root" layer (called "gameLayer") the same size as the original. Then during the UIPanGestureRecognizer, I move the bomb element from "gameLayer" into my UIView.layer. Then while I am testing for a AIEnemyUnit, I only run the hitTest on the "gameLayer".
- UIView.layer --------- gameLayer
| |
dragObj(bomb) gameElements
|
bomb