使用 UITapGestureRecognizer 防止按钮在视图后面时触发

Prevent button to trigger when it's behind a view with UITapGestureRecognizer

我有以下设置:

  1. zPosition = 0 处的蓝色背景
  2. zPosition = 0 处的黄色按钮带有打印操作 "Button tapped"
  3. 具有灰色背景和 0.8 alpha 的 zPosition = 1 的 UIView 以及带有打印操作的 UITapGestureRecognizer "Grey view tapped"

当我点击灰色区域时,会打印 "Grey view tapped"。 但是,如果我点击黄色按钮的位置,则会打印 "Button tapped" 。 我希望总是打印 "Grey view tapped" 因为那个视图在按钮前面。 如何防止触发视图后面的按钮?

我知道我可以将按钮设置为 .isEnabled = false 但这不是一个合适的解决方案,因为灰色背景是在父视图控制器中创建的 我所有的视图都是继承的。

我将灰色视图设置为 .isUserInteractionEnabled = true(即使它是默认值),如下所述:

我想使用 Apple Documentation 但问题是有一个按钮和一个手势识别器而不是多个手势识别器。

知道如何正确执行此操作吗?

您可以使用此方法检查触摸是否在按钮上,然后触发您的操作。

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let firstTouch = touches.first {
    let hitView = self.view.hitTest(firstTouch.location(in: yourBtn), with: event)

    if hitView === yourBtn {
        print("touch is inside")
    } else {
        print("touch is outside")
    }
 }
}

@Daljeet 带我找到解决方案。使用 Debug View Hierarchy 我意识到我的按钮位于视图的顶部。我的错误是因为我没有意识到 UIView.layer.zPosition 和层次结构中子视图的顺序之间的区别。一个视图可以绘制在另一个视图的后面,但仍然位于视图层次结构的前面。

解决方案是使用 view.bringSubviewToFront(greyView)

请注意,如果您在调用最后一行代码后添加按钮,该按钮将放置在视图层次结构的顶部