Actually there is no difference between the .Cancelled and .Failed states. Both leading to gesture recognizer failing to handle the gesture. I guess it is just a naming convention.
Though, the difference is also how both states affect the gesture handling.
It depends of what the previous state of the gesture recognizer was.
- If the gesture recognizer transitioned from
.Possible
to .Began
in touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
(UITouchPhase.Began
phase of the touch), than in the same method to .Failed
or .Cancelled
, the next gesture recognizer in the queue(attached to a view) will have the opportunity to handle the gesture. No action message will be send.
- But if the gesture recognizer transitioned from .Possible to .Began in
touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
(UITouchPhase.Began
phase of the touch), than in the touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent)
method to .Failed
or .Cancelled
the gesture recognition will simply fail and nothing will happen. But the action message will be send anyway.
- If you comment out the code on line 8, then the gesture recognition will fail and the next gesture recognizer attached to the view will have the opportunity to handle the gesture.
So here the view controller:
class ViewController: UIViewController {
func panHandler(sender: UIPanGestureRecognizer) {
print("panHandler")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let customRecognizer = CustomGestureRecognizer(target: self, action: #selector(ViewController.customHandler(_:)))
view.addGestureRecognizer(customRecognizer)
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(ViewController.panHandler(_:)))
view.addGestureRecognizer(panRecognizer)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func customHandler(c: CustomGestureRecognizer) {
print("customHandler")
}
}
and here a custom gesture recognizer:
import UIKit
import UIKit.UIGestureRecognizerSubclass
class CustomGestureRecognizer: UIGestureRecognizer {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
state = .Began
if touches.count == 1 {
//state = .Failed
}
print("CustomGestureRecognizer.touchesBegan")
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesMoved(touches, withEvent: event)
if state == .Failed {
return
}
if touches.count == 1 {
state = .Failed //.Cancelled
}
state = .Changed
print("CustomGestureRecognizer.touchesMoved")
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesEnded(touches, withEvent: event)
state = .Ended
print("CustomGestureRecognizer.touchesEnded")
}
}
Just comment/uncomment the code on lines 8, 10 and 23 to see the differences.