【问题标题】:Why does one have to use CALayer's presentationLayer for hit-testing?为什么必须使用 CALayer 的presentationLayer 进行命中测试?
【发布时间】:2010-02-04 11:17:03
【问题描述】:

我正在开发一个 Cocoa Touch 应用程序,并尝试通过确定视图层的哪个子层被触摸来处理触摸。我的控制器代码如下所示:

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

这不起作用。如果我在子层的底部点击它会起作用,但不是在顶部。经过一个小时的拉扯和谷歌搜索,我终于发现如果使用表示层而不是层本身进行命中测试,它会起作用:

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

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

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

【问题讨论】:

  • self.view的类是什么:UIView还是CALayer?
  • self.view 是一个 UIView。我已经更正了上面的代码以使用“self.view.layer”,因为它应该是。

标签: cocoa cocoa-touch core-animation calayer


【解决方案1】:

根据CALayer documentation,模型和展示树之间在展示给用户的内容方面似乎存在差异(取决于正在进行的动画)。对于命中测试,presentationLayer方法中有参考:

例如,发送一个 hitTest: 给presentationLayer的消息将 查询的表示值 层树。

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

【讨论】:

    【解决方案2】:

    Kristopher,我也有一个非常相似的问题。但是,当我将点转换为超级图层或超级视图坐标系时,它工作得很好。我没有使用表示层。

        //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]];
    

    这会返回我被触摸的层,至少现在是这样。如果您认为这是一种错误的方法,请告诉我们,我应该改用表示层。

    【讨论】:

      猜你喜欢
      • 2018-01-25
      • 2011-02-26
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      相关资源
      最近更新 更多