Uiswipegesturerecognizer Doesn't Recognize Swipe Gesture Initiated Outside the View

How to detect end of UISwipeGestureRecognizer?

I figured it out, actually it was quite easy, instead of using UISwipeGestureRecognizer to detect swipes I detected it myself using event handling

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
self.initialPosition = [touch locationInView:self.view];

}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint movingPoint = [touch locationInView:self.view];
CGFloat moveAmt = movingPoint.y - self.initialPosition.y;
if (moveAmt < -(minimum_detect_distance)) {
[self handleSwipeUp];
} else if (moveAmt > minimum_detect_distance) {
[self handleSwipeDown];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self reset];

}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
[self reset];
}

I haven't subclassed UIGestureRecognizer but did the event handling in the required view controller only, as in reset method I am resetting few variable, counters and timers belonging to the view controller.

How to recognize swipe in all 4 directions

You need to have one UISwipeGestureRecognizer for each direction. It's a little weird because the UISwipeGestureRecognizer.direction property is an options-style bit mask, but each recognizer can only handle one direction. You can send them all to the same handler if you want, and sort it out there, or send them to different handlers. Here's one implementation:

override func viewDidLoad() {
super.viewDidLoad()

let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
swipeRight.direction = .right
self.view.addGestureRecognizer(swipeRight)

let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
swipeDown.direction = .down
self.view.addGestureRecognizer(swipeDown)
}

@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {

if let swipeGesture = gesture as? UISwipeGestureRecognizer {

switch swipeGesture.direction {
case .right:
print("Swiped right")
case .down:
print("Swiped down")
case .left:
print("Swiped left")
case .up:
print("Swiped up")
default:
break
}
}
}

Swift 3:

override func viewDidLoad() {
super.viewDidLoad()

let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeRight.direction = UISwipeGestureRecognizerDirection.right
self.view.addGestureRecognizer(swipeRight)

let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeDown.direction = UISwipeGestureRecognizerDirection.down
self.view.addGestureRecognizer(swipeDown)
}

func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.right:
print("Swiped right")
case UISwipeGestureRecognizerDirection.down:
print("Swiped down")
case UISwipeGestureRecognizerDirection.left:
print("Swiped left")
case UISwipeGestureRecognizerDirection.up:
print("Swiped up")
default:
break
}
}
}

Using Swipe Gesture and Touches Began/Moved/Ended at the same time

Should be:

self.leftSwipeGestureRecognizer.cancelsTouchesInView = YES

This mean: touches are cancelled in case gesture was recognized, otherwise, touches began/moved/ended called.

From documentation:

When this property is YES (the default) and the receiver recognizes
its gesture, the touches of that gesture that are pending are not
delivered to the view and previously delivered touches are cancelled
through a touchesCancelled:withEvent: message sent to the view. If a
gesture recognizer doesn’t recognize its gesture or if the value of
this property is NO, the view receives all touches in the multi-touch
sequence.



Related Topics



Leave a reply



Submit