How can I catch any touch up event in my application view without affecting any other event in subview or subview of the subview?
Currently whenever I add UILongPressGestureRecognizer to my root view, all other addTarget
functions break in subviews and their subviews.
func gestureRecognizer(_: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith: UIGestureRecognizer) -> Bool {
return true
}
override func viewDidLoad() {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
button.setTitle("Click me", for: .normal)
button.addTarget(self, action: #selector(buttonClick), for: .touchDown)
self.view.addSubview(button)
initLongTapGesture() // This kills the button click handler.
}
func initLongTapGesture () {
let globalTap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
globalTap.delegate = self
globalTap.minimumPressDuration = 0
self.view.addGestureRecognizer(globalTap)
}
@objc func tapHandler(gesture: UITapGestureRecognizer) {
if ([.ended, .cancelled, .failed].contains(gesture.state)) {
print("Detect global touch end / up")
}
}
@objc func buttonClick() {
print("CLICK") // Does not work when initLongTapGesture() is enabled
}
CodePudding user response:
The immediate solution to allow the long press gesture to work without preventing buttons from working is to add the following line:
globalTap.cancelsTouchesInView = false
in the initLongTapGesture
function. With that in place you don't need the gesture delegate method (which didn't solve the issue anyway).
The big question is why are you setting a "long" press gesture to have a minimum press duration of 0?
If your goal is to monitor all events in the app then you should override the UIApplication
method sendEvent
. See the following for details on how to subclass UIApplication
and override sendEvent
:
Issues in overwriting the send event of UIApplication in Swift programming
You can also go through these search results:
https://stackoverflow.com/search?q=[ios][swift] override UIApplication sendEvent
Another option for monitoring all touches in a given view controller or view is to override the various touches...
methods from UIResponder
such as touchesBegan
, touchesEnded
, etc. You can override these in a view controller class, for example, to track various touch events happening within that view controller.
Unrelated but it is standard to use the .touchUpInside
event instead of the touchDown
event when handing button events.