UIPanGestureRecognizer do something immediately when touched UIPanGestureRecognizer do something immediately when touched ios ios

UIPanGestureRecognizer do something immediately when touched


I needed to do this too, and Jake's suggestion worked perfectly for me. In case it helps anyone who comes across this in the future, here is my subclass implementation of UIPanGestureRecognizer (the header remains unchanged):

#import "ImmediatePanGestureRecognizer.h"#import <UIKit/UIGestureRecognizerSubclass.h>@implementation ImmediatePanGestureRecognizer- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {    [super touchesBegan:touches withEvent:event];    self.state = UIGestureRecognizerStateBegan;}@end

This is all you need—this will fire as soon as you put your finger down on the view, update as soon as you move your finger a single point in any direction, and provide the functionality of a regular UIPanGestureRecognizer (like translationInView and velocityInView) before a regular one would've fired, all without breaking any existing functionality.


Copypaste for Swift 5, 2020

import UIKit // (nothing extra needed to import with Swift5)fileprivate class ImmediatePanG: UIPanGestureRecognizer {    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {        super.touchesBegan(touches, with: event)        self.state = .began    }}


I have implemented George WS's answer. With a little testing I realized that additional touch events that occur after the initial touch, but before the initial touch ends are not being properly handled. Here is my updated implementation. It's a bit naive, but prevents bizarre behavior caused by the UIGestureRecognizerStateBegan happening multiple times.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {    if (self.state >= UIGestureRecognizerStateBegan) {        return;    }    [super touchesBegan:touches withEvent:event];    self.state = UIGestureRecognizerStateBegan;}


Swift 3/4/5 Solution

class InstantPanGestureRecognizer: UIPanGestureRecognizer {    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {        if self.state == .began { return }        super.touchesBegan(touches, with: event)        self.state = .began    }}