Question

I have an UISrollView called templateView. I must add to it a swipe gesture to allow the user to swipe left/right to see another templates. The problem is that most of times the user can't swipe easily because the view scrolls down/up instead of swiping to another view. his finger needs to be aligned strictly horizontal to swipe to another page and this isn't acceptable from a user experience perspective.

Any idea how to handle such cases? Is there a way to implement an angle for detecting the swipe gesture? or, is there a way to do it as a custom uigesture for detecting oblique lines with a specific angle?

Thanks in advance.

Was it helpful?

Solution

Try to implement UIGestureRecognizer Delegate method. This method is called when recognition of a gesture by either gestureRecognizer or otherGestureRecognizer would block the other gesture recognizer from recognizing its gesture. Note that returning YES is guaranteed to allow simultaneous recognition.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer  
    {
        return YES;
    }

Reference: UIGestureRecognizer Protocol

Do not forget to assign delegate, when you are initializing your swipe gesture.

UPDATE 1 CREATING YOUR OWN GESTURE

You always can subclass UIGestureRecognizer class and implement touchesBegan, touchesMoved, touchesEnded methods - manually managing the states of the gesture depending on your own needs.

I am posting some sample code of implementing custom EdgeGestureRecognizer for your better understanding.

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

    // if not single finger, then fail

    if ([touches count] != 1)
    {
        self.state = UIGestureRecognizerStateFailed;
        return;
    }
   //put here some logics for your case. For instance, you can register
   //here your first touch location, it will help
   //you to calculate the angle after.
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    if (self.state == UIGestureRecognizerStateFailed) return;

    UITouch *touch = touches.anyObject;
    self.previousPoint = self.currentPoint;
    self.previousPointTime = self.currentPointTime;
    self.currentPoint = [touch locationInView:self.view];
    self.currentPointTime = touch.timestamp;

    if (self.state == UIGestureRecognizerStatePossible)
    {
        CGPoint translate = CGPointMake(self.currentPoint.x - self.startPoint.x, self.currentPoint.y - self.startPoint.y);

        // see if we've moved the necessary minimum distance

        if (sqrt(translate.x * translate.x + translate.y * translate.y) >= self.minimumRecognitionDistance)
        {
            // recognize if the angle is roughly horizontal, otherwise fail

            double angle = atan2(translate.y, translate.x);

            if ([self isAngleCloseEnough:angle])
                self.state = UIGestureRecognizerStateBegan;
            else
                self.state = UIGestureRecognizerStateFailed;
        }
    }
    else if (self.state == UIGestureRecognizerStateBegan)
    {
        self.state = UIGestureRecognizerStateChanged;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top