In my project, I have the main view, in which I add a UITapGestureRecognizer
, and inside this main view, I have a subview that is a custom UIControl
, which I will call UICustomButton
.
The UICustomButton
overrides the following methods of UIControl
:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
pressAnimation()
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
releaseAnimation()
listener?.onClick(sender: self)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
releaseAnimation()
}
The problem I am having is, all "click touches" are hitting the following callbacks:
touchesBegan
touchesCancelled
The touchesEnded
callback is not being called, it's kinda being ignored and I don't know why.
How can I make touchesEnded
be called instead of touchesCancelled
on a touch action?
Some facts:
UITapGestureRecognizer
from the parent view, everything works fine;supers
and overriding all touches
methods, the touchesCancelled
is called =/;touchesEnded
is called :o.This is the correct behaviour for a view that has a gesture recogniser attached.
The UIGestureRecognizer
documentation says "If a gesture recognizer recognizes its gesture, the remaining touches for the view are cancelled":
https://developer.apple.com/documentation/uikit/uigesturerecognizer
The property cancelsTouchesInView
(which defaults to true
), determines whether or not touches are cancelled when a gesture is recognized:
https://developer.apple.com/documentation/uikit/uigesturerecognizer/1624218-cancelstouchesinview
Because a long touch and a swipe are not recognized by a tap recognizer, it doesn't interfere with them. It only intervenes when it recognizes a tap.
If you set the recognizer's cancelsTouchesInView
property to false
, then the touches shouldn't be cancelled, and the touchesEnded(_:with:)
method will be called as usual.
You can set that property either in code or in Interface Builder (if you added your gesture recognizer by dragging it out in your storyboard).