如何使用 HitTest 获得最前层而不是最深层

How does one get the front-most layer instead of the deepest layer using HitTest

好吧,我只是浪费了 2 天时间。
最简单的示例:我有 2 个 UIView,它们从屏幕顶部到底部正在 动画。经过大量研究后,我发现当 UIView 正在动画时,您可以 "touch/trigger" 触摸事件的唯一方法是通过使用 presentationLayer 属性 的 HitTest。

touchBegan 方法内部

    x as! UIView

   if x.layer.presentationLayer()!.hitTest(touchlocation) != nil {
    x.alpha = 0
    //Layer touched
    }

情况: 在动画期间,第一个 UIView overlaps\upon 第二个 UIView。那时我是 "touching" 最顶级的 UIView。
问题: HitTest return lowest\deepest层,所以底层的UIView层会被识别。
问题:如何获取 first/frontmost UIView 层而不是最深的层?

基于 our chat 我们发现了实际发生的事情。

基本上,为了检测触摸,您要遍历视图控制器中的所有子视图,并对它们的每个 presentationLayer 执行 hitTest 以检测触摸 动画期间.

我们发现了一些问题:

  1. hitTest 正在返回当前子视图 (x) 层的子层,并在不知不觉中与另一个视图 (y) 合并。
  2. 用于遍历子视图的 for 循环一旦找到目标就没有使用 break 语句,导致上面 1 中的混乱。
  3. 通过按正常顺序遍历子视图,由于 addSubviewsubviews 的结构方式,视图被从后向前搜索。

解决方案

最终解决方案是通过以下方式解决这些问题:

  • 使用 for x in self.view.subviews.reverse()
  • 以相反的顺序遍历子视图
  • 正在测试 hitTest 返回的层是否是 当前正在测试的视图(伪代码)if layerThatWasHit.superlayer == x.presentationLayer()
  • 在点击视图的 if 中添加 break 语句 检测到终止 for 循环并防止多次执行 导致点击其中一个动画视图的代码。