如何使用 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
以检测触摸 动画期间.
我们发现了一些问题:
hitTest
正在返回当前子视图 (x
) 层的子层,并在不知不觉中与另一个视图 (y
) 合并。
- 用于遍历子视图的
for
循环一旦找到目标就没有使用 break
语句,导致上面 1
中的混乱。
- 通过按正常顺序遍历子视图,由于
addSubview
和 subviews
的结构方式,视图被从后向前搜索。
解决方案
最终解决方案是通过以下方式解决这些问题:
- 使用
for x in self.view.subviews.reverse()
以相反的顺序遍历子视图
- 正在测试
hitTest
返回的层是否是
当前正在测试的视图(伪代码)if layerThatWasHit.superlayer == x.presentationLayer()
- 在点击视图的
if
中添加 break
语句
检测到终止 for
循环并防止多次执行
导致点击其中一个动画视图的代码。
好吧,我只是浪费了 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
以检测触摸 动画期间.
我们发现了一些问题:
hitTest
正在返回当前子视图 (x
) 层的子层,并在不知不觉中与另一个视图 (y
) 合并。- 用于遍历子视图的
for
循环一旦找到目标就没有使用break
语句,导致上面1
中的混乱。 - 通过按正常顺序遍历子视图,由于
addSubview
和subviews
的结构方式,视图被从后向前搜索。
解决方案
最终解决方案是通过以下方式解决这些问题:
- 使用
for x in self.view.subviews.reverse()
以相反的顺序遍历子视图
- 正在测试
hitTest
返回的层是否是 当前正在测试的视图(伪代码)if layerThatWasHit.superlayer == x.presentationLayer()
- 在点击视图的
if
中添加break
语句 检测到终止for
循环并防止多次执行 导致点击其中一个动画视图的代码。