Detecting Any Touch in a View in iOS

My problem was that I had a sort of shelf view that would pop up to display information when a pin was tapped on a map view.  The shelf only covered part of the map view.  I wanted the view to go away when any part of the still visible map view was tapped.  Fairly common behavior.  On the interwebs, however I got a convoluted answer about using a wildcard gesture recognizer from Stack Overflow [See http://stackoverflow.com/questions/1049889/how-to-intercept-touches-events-on-a-mkmapview-or-uiwebview-objects ].

But, it turns out all UIViews inherit from UIResponder, which has a number of touch related functions.  The one that’s important to me is touchesBegan, which fires any time there’s a touch on the view.   So when I add the shelf to the super view (in my case the map view) I can also add a transparent overlay view.  I set it to hidden until the shelf pops up, then when someone clicks on that overlay a delegate function from the overlay tells the VC that the overlay touchesBegan has happened.  In that function I dismiss the shelf view and hide the overlay.

import MapKit

protocol ViewTouchDelegate: class {
 func ViewTapped()
}

OverlayView: UIView {

//normally would call this parameter "delegate" but if using specialized view "delegate" may already be used.
weak var viewTouchDelegate: ViewTouchDelegate?
...

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {


    self.mapViewTouchDelegate?.mapViewTapped()
    super.touchesBegan(touches, withEvent: event)
 }

 

And yet… since the map view is inherits from UIResponder… I can just subclass the map view, add the protocol/delegate methods and not even use an overlay, remembering that in the map view touchesBegan function to include super.touchesBegan so that all the functionality of gestures still work.  The advantage of this approach is that when the user touches anywhere on the map, not only is my dismiss shelf function called but also the other functionality still works – tapping on a pin still does whatever it’s going to do.  If I use an overlay that first touch simply fires that delegate method, then I have to use my normal gestures, or possibly pass the gestures through some communication pattern.  So in my case, it seems easier to just subclass map view and override it’s touchesBegan method.  An overlay view would be useful if there were a number of different views underneath the shelf view, instead of just a map.