2

How do you implement a swipe with an UIGestureRecognizer subclass?

(in case you're wondering why I'd like to do this instead of using UISwipeGestureRecognizer, it's because I want to add swipe recognition to Chameleon's UIKit port)

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
hpique
  • 119,096
  • 131
  • 338
  • 476
  • +1 for the mentioned project and for the question! Do you have some news on this? I also need something like this, the only thing i found is [this](http://www.raywenderlich.com/6567/uigesturerecognizer-tutorial-in-ios-5-pinches-pans-and-more), see the last section, maybe can help. – Mat Apr 18 '12 at 21:38

1 Answers1

1

My first go at it (also on Github):

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

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint movedLocation = [touch locationInView:self.view];
    CGFloat distance = _distance(_beganLocation, movedLocation);

    if (distance < SWIPE_MIN_DISTANCE) return;

    CGFloat angle = _angle(_beganLocation, movedLocation);
    int direction = -1;
    if (angle > 270 - SWIPE_MAX_ANGLE && angle < 270 + SWIPE_MAX_ANGLE) {
        direction = UISwipeGestureRecognizerDirectionUp;
    }
    if (angle > 180 - SWIPE_MAX_ANGLE && angle < 180 + SWIPE_MAX_ANGLE) {
        direction = UISwipeGestureRecognizerDirectionLeft;
    }
    if (angle > 90 - SWIPE_MAX_ANGLE && angle < 90 + SWIPE_MAX_ANGLE) {
        direction = UISwipeGestureRecognizerDirectionDown;
    }
    if ((angle > 360 - SWIPE_MAX_ANGLE && angle <= 360) || (angle >= 0 && angle <= SWIPE_MAX_ANGLE)) {
        direction = UISwipeGestureRecognizerDirectionRight;
    }

    if (direction == -1) {
      self.state = UIGestureRecognizerStateFailed;
    } else {
      self.state = self.direction == direction ? UIGestureRecognizerStateRecognized : UIGestureRecognizerStateFailed;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    self.state = UIGestureRecognizerStateFailed;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    self.state = UIGestureRecognizerStateFailed;
}

Auxiliary functions:

static CGFloat _distance(CGPoint point1,CGPoint point2)
{
    CGFloat dx = point2.x - point1.x;
    CGFloat dy = point2.y - point1.y;
    return sqrt(dx*dx + dy*dy);
};

static CGFloat _angle(CGPoint start, CGPoint end)
{
    CGPoint origin = CGPointMake(end.x - start.x, end.y - start.y); // get origin point to origin by subtracting end from start
    CGFloat radians = atan2f(origin.y, origin.x); // get bearing in radians
    CGFloat degrees = radians * (180.0 / M_PI); // convert to degrees
    degrees = (degrees > 0.0 ? degrees : (360.0 + degrees)); // correct discontinuity
    return degrees;
}

It should be noted that Chameleon's implementation of gesture recognizers is incomplete and contains logic most likely specific to Twitterrific. Our fork contains further modifications.

hpique
  • 119,096
  • 131
  • 338
  • 476