我有一个UIView,其中包含一个我使用CALayers添加为子层的图形。它是一个红色的正方形,中间有一个蓝色的三角形。我可以使用以下代码确定哪个形状已被触摸:
CGPoint location = [gesture locationInView:self.view];
CALayer* layerThatWasTapped = [self.view.layer hitTest:location];
NSLog(@"Master Tap Location: %@", NSStringFromCGPoint(location));
NSLog(@"Tapped Layer Name: %@", layerThatWasTapped.name);
NSLog(@"Tapped Layer Parent: %@", layerThatWasTapped.superlayer.name);
int counter = layerThatWasTapped.superlayer.sublayers.count;
NSArray * subs = layerThatWasTapped.superlayer.sublayers;
//Loop through all sublayers of the picture
for (int i=0; i<counter; i++) {
CALayer *layer = [subs objectAtIndex:i];
CAShapeLayer* loopLayer = (CAShapeLayer*)layerThatWasTapped.modelLayer;
CGPathRef loopPath = loopLayer.path;
CGPoint loopLoc = [gesture locationInView:cPage];
loopLoc = [self.view.layer convertPoint:loopLoc toLayer:layer];
NSLog(@"loopLoc Tap Location: %@", NSStringFromCGPoint(loopLoc));
//determine if hit is on a layer
if (CGPathContainsPoint(loopPath, NULL, loopLoc, YES)) {
NSLog(@"Layer %i Name: %@ Hit",i, layer.name);
} else {
NSLog(@"Layer %i Name: %@ No Hit",i, layer.name);
}
}我的问题在于三角形边界与正方形重叠的区域。即使命中位于三角形路径之外,这也会导致三角形记录命中。这是一个简化的例子(我可能在视图中堆叠了许多重叠的形状),有没有一种方法可以循环遍历所有的子层并点击每个子层,看看它是否位于攻击点的下面?或者,有没有办法让我的图层的边界与它们的路径相匹配,这样命中只发生在可见区域?
发布于 2011-12-16 11:38:17
因为您使用的是CAShapeLayer,所以这非常简单。创建CAShapeLayer的子类并覆盖其containsPoint:方法,如下所示:
@implementation MyShapeLayer
- (BOOL)containsPoint:(CGPoint)p
{
return CGPathContainsPoint(self.path, NULL, p, false);
}
@end确保无论您在何处分配CAShapeLayer,都要将其更改为分配MyShapeLayer:
CAShapeLayer *triangle = [MyShapeLayer layer]; // this way
CAShapeLayer *triangle = [[MyShapeLayer alloc] init]; // or this way最后,请记住,在调用-[CALayer hitTest:]时,您需要传入超层坐标空间中的一个点:
CGPoint location = [gesture locationInView:self.view];
CALayer *myLayer = self.view.layer;
location = [myLayer.superlayer convertPoint:location fromLayer:myLayer];
CALayer* layerThatWasTapped = [myLayer hitTest:location];https://stackoverflow.com/questions/8512384
复制相似问题