Ios 防止按钮在启动时触发';它位于具有UITapGestureRecognitor的视图后面

Ios 防止按钮在启动时触发';它位于具有UITapGestureRecognitor的视图后面,ios,swift,xcode,swift5,Ios,Swift,Xcode,Swift5,我有以下设置: zPosition=0处的蓝色背景 zPosition=0处的黄色按钮,带有打印“点击按钮”的操作 UIView带有灰色背景,zPosition=1处为0.8 alpha,带有UIAPTgestureRecognitor,可打印“灰色视图” 当我点击灰色区域时,“灰色视图点击”被打印出来。 但如果我点击黄色按钮的位置,“按钮点击”就会被打印出来。 我希望总是打印“灰色视图点击”,因为该视图位于按钮前面。 如何防止视图后面的按钮被触发 我知道我可以将按钮设置为.isEnabled

我有以下设置:

  • zPosition=0处的蓝色背景
  • zPosition=0处的黄色按钮,带有打印“点击按钮”的操作
  • UIView带有灰色背景,zPosition=1处为0.8 alpha,带有UIAPTgestureRecognitor,可打印“灰色视图”
  • 当我点击灰色区域时,“灰色视图点击”被打印出来。 但如果我点击黄色按钮的位置,“按钮点击”就会被打印出来。 我希望总是打印“灰色视图点击”,因为该视图位于按钮前面。 如何防止视图后面的按钮被触发

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

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

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


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

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

    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")
        }
     }
    }
    
    override func touchesend(touch:Set,带有事件:UIEvent?){
    如果let firstTouch=touch.first{
    让hitView=self.view.hitTest(firstTouch.location(in:yourBtn),with:event)
    如果hitView==您的BTN{
    打印(“触摸在里面”)
    }否则{
    打印(“触摸在外”)
    }
    }
    }
    
    @Daljeet引导我找到解决方案。使用调试视图层次结构,我意识到我的按钮位于视图的顶部。我的错误是因为我没有意识到UIView.layer.zPosition和层次结构中子视图的顺序之间的区别。一个视图可以在另一个视图后面绘制,但在视图层次结构中可以位于前面

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


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

    我不认为您的按钮位于视图的后面。调试视图层次结构。您的灰色区域是否始终位于按钮上方?如果没有,可能取决于视图的z位置,您可以启用和禁用按钮,以便获得预期的功能?谢谢@Daljeet,我能够找到解决方案。我把它作为一个答案贴了出来。我试过那段代码并添加了一条打印语句,结果发现它从来没有被调用过