为什么需要使用CALayer的presentationLayer进行命中测试?

问题描述:

我正在研究Cocoa Touch应用程序,并试图通过确定触摸视图图层的哪个子图层来处理触摸。我的控制器代码如下所示:为什么需要使用CALayer的presentationLayer进行命中测试?

CALayer *hitLayer = [self.view.layer hitTest:point]; 

这不起作用。如果我在底层的底部敲击,但不在顶部,它会起作用。的拔头发和谷歌搜索一小时后,我终于想通了,它的工作原理,如果一个使用表现层做命中测试层本身,而不是:

CALayer *hitLayer = [self.view.layer.presentationLayer hitTest:point]; 

所以,我已经解决了我的问题,但我的问题是:为什么?

我已阅读了Core Animation指南,并且我明白表示树和呈现树可以与对象模型树不同。但我不明白为什么表示树(显然)会有不同的命中测试行为。表示树和对象模型不会有相同的框架,边界等吗?

+0

什么是self.view类:UIView或CALayer? – 2010-02-04 13:23:04

+0

self.view是一个UIView。我已经更正了上面的代码,以便像使用“self.view.layer”一样。 – 2010-02-04 15:34:55

根据CALayer documentation,模型和表示树之间似乎存在差别,它与呈现给用户的内容(取决于正在进行的动画)有关。对于命中测试,存在在presentationLayer方法的引用:

例如,发送一个则hitTest:对表示层 消息将 查询 层树的呈现值。

所以我怀疑只有表示层有正确的几何信息来执行命中测试。

克里斯托弗,我也有一个非常类似的问题。但是,当我将该点转换为超级图层或超级视图坐标系时,它可以很好地工作。我没有使用表示层。

//Identify the touch point in the view. Using UITapRecognizer 
CGPoint loc = [recognizer locationInView:recognizer.view]; 

//convert the point to superview co-ordinates and then identify the layer using hit test. 
CALayer *layer = [self.layer hitTest:[self convertPoint:loc toView:self.superview]]; 

这会返回至少现在被触摸的图层。让我们知道如果您认为这是一种错误的方法,我应该使用表示层。