2
votes

I have the following setup :

enter image description here

  1. Blue background at zPosition = 0
  2. Yellow button at zPosition = 0 with an action to print "Button tapped"
  3. UIView with grey background and 0.8 alpha at zPosition = 1 with a UITapGestureRecognizer with an action to print "Grey view tapped"

When I tapped at the grey area, "Grey view tapped" is printed. But if I tapped at the location of the yellow button, "Button tapped" is printed. I expected to always have printed "Grey view tapped" because that view is in front of the button. How can I prevent the button that is behind a view to be triggered ?

I know that I can set the button to .isEnabled = false but that is not a suitable solution since the grey background is created in a parent view controller from witch all my views are inheriting.

I set the grey view to .isUserInteractionEnabled = true (even if it's the default value) as stated here : In Stackoverflow

I thought using Apple Documentation but the problem is that there are a button and a gesture recognizer instead of multiple gesture recognizers.

Any idea on how to do this properly?

2
I don't think so your button is behind the view. Debug View Hierarchy.Daljeet
Will your grey area is always above the button? If not, maybe depending upon the z-position of the view, you can enable and disable the button so that you get the expected feature?mAc
Thank you @Daljeet, I was able to find the solution. I posted it as an answerNicoC

2 Answers

2
votes

@Daljeet lead me to the solution. Using the Debug View Hierarchy I realised that my button was on top of the the view. My mistake was because I didn't realised the difference between UIView.layer.zPosition and the order of subviews in the hierarchy. A view can be drawn behind another view but nonetheless be in front in the View Hierarchy.

The solution was to use view.bringSubviewToFront(greyView)

Be aware that if you add the button after calling that last line of code, the button will be placed on top of the View Hierarchy

1
votes

you can use this method to check if the touch was on the button and then trigger your action.

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")
    }
 }
}