Reputation: 8090
From the Apple documentation
A swipe is a discrete gesture, and thus the associated action message is sent only once per gesture.
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent*)event
also doesn't gets called when I use UISwipeGestureRecognizer
How can I detect when the user lifts his finger?
Upvotes: 3
Views: 3883
Reputation: 789
If you use scrollView, you can detect contentOffset of it
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y < -100 { // how you needed
// do what you need
}
}
Upvotes: 0
Reputation: 87
UISwipeGestureRecognizer is a discrete gesture as the Apple documentation said, so you need to use a continuous gesture, in this case use UIPanGestureRecognizer.
Here is the code:
- (void)viewDidLoad{
[super viewDidLoad];
// add pan recognizer to the view when initialized
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecognized:)];
[panRecognizer setDelegate:self];
[yourView addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on
}
-(void)panRecognized:(UIPanGestureRecognizer *)sender{
CGPoint distance = [sender translationInView: yourView];
if (sender.state == UIGestureRecognizerStateEnded) {
[sender cancelsTouchesInView];
if (distance.x > 70 && distance.y > -50 && distance.y < 50) { // right
NSLog(@"user swiped right");
NSLog(@"distance.x - %f", distance.x);
} else if (distance.x < -70 && distance.y > -50 && distance.y < 50) { //left
NSLog(@"user swiped left");
NSLog(@"distance.x - %f", distance.x);
}
if (distance.y > 0) { // down
NSLog(@"user swiped down");
NSLog(@"distance.y - %f", distance.y);
} else if (distance.y < 0) { //up
NSLog(@"user swiped up");
NSLog(@"distance.y - %f", distance.y);
}
}
}
Don't forget to add UIGestureRecognizerDelegate.
Upvotes: 1
Reputation: 38142
I think better you need to examine the state property of the gesture recognizer:
- (void)swipe:(UISwipeGestureRecognizer *)recognizer
{
CGPoint point = [recognizer locationInView:[recognizer view]];
if (recognizer.state == UIGestureRecognizerStateBegan)
NSLog(@"Swipe began");
else if (recognizer.state == UIGestureRecognizerStateEnded)
NSLog(@"Swipe ended");
}
Upvotes: 2
Reputation: 8090
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.
Upvotes: 3