CALayer上的hitTest – 你如何找到被击中的实际图层?

情况:需要找到用户触摸的图层。

问题:Apple表示我们应该使用[CALayer presentationLayer]进行命中测试,以便它代表当时屏幕上的实际内容(它捕捉动画中期等信息)。

…除了:presentationLayer不返回原始图层,它返回它们的副本……所以:hitTest将返回一个全新的CALayer实例,该实例与原始实例不同。

我们如何找到被击中的实际CALayer?

例如

CALayer* x = [CALayer layer]; CALayer* y = [CALayer layer]; [self.view.layer addSublayer: x]; [self.view.layer addSublayer: y]; ... CALayer* touchedLayer = [self.view.layer.presentationLayer hitTest:touchPoint]; 

…但是,触摸的是“x”,还是“y”?

 if( touchedLayer == x ) // this won't work, because touchedLayer is - by definition from Apple - a new object 

亚当的回答是正确的,并帮助了我。 这是我使用的代码,可以帮助其他人。

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint touchPoint = [(UITouch*)[touches anyObject] locationInView:self]; CALayer *touchedLayer = [self.layer.presentationLayer hitTest:touchPoint]; // is a copy of touchedLayer CALayer *actualLayer = [touchedLayer modelLayer]; // returns the actual layer NSLog (@"touchedLayer: %@", touchedLayer); NSLog (@"actualLayer: %@", actualLayer); } 

啊! 刚刚弄明白这一点,阅读一篇关于CALayer不同问题的邮件列表post。

在调用[CALayer presentationLayer]并使用图层树的“表示克隆”之后,您可以获取该树中的任何对象,并在其上调用[CALayer modelLayer]以获取原始参考对象在同一位置。原始树

这个参考是稳定的(测试 – 它的工作原理)。

Apple的文档有点……模糊不清……就这一点而言。 他们暗示它“有时”会失败(“ ……结果未定义 ”) – 但现在对我来说已经足够了。