Detect diagonal swipe gestures in a UIView
Asked Answered
B

5

4

I want to detect a two-finger diagonal swipe that starts from the bottom right of the screen to the middle. I tried adding UISwipeGestureRecognizer with direction set as "UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionLeft" but to no vail as the handler is getting invoked even if I start the swipe from the middle of the screen to the top left.

Do I need to sub-class UIGestureRecognizer or can I handle this using touchesBegan and touchesMoved ?

Benedetto answered 29/7, 2012 at 6:43 Comment(0)
B
0

Thanks Guys!

I ended up writing custom code in touchesBegan, touchesMoved and touchesEnded and ot works like charm.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    if ([touches count] == 2) {
        CGPoint nowPoint = [[touches anyObject] locationInView:self];
        if( nowPoint.x >= ALLOWED_X)
            swipeUp = YES;
    }

    [super touchesBegan:touches withEvent:event];
}


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

    if ([touches count] == 2 && swipeUp) {

        CGPoint nowPoint = [[touches anyObject] locationInView:self];
        CGPoint prevPoint = [[touches anyObject] previousLocationInView:self];

        if( nowPoint.x <= prevPoint.x && nowPoint.y <= prevPoint.y){
        }
        else {
            swipeUp = NO;
        }
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    CGPoint nowPoint = [[touches anyObject] locationInView:self];

    if ([touches count] == 2 && swipeUp && nowPoint.x <= DELTA_X && nowPoint.y <= DELTA_Y) {
        NSLog(@"Invoke Method");
    }
    swipeUp = NO;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    swipeUp = NO;
}
Benedetto answered 29/7, 2012 at 7:13 Comment(0)
E
1

the touches method of cause can do every Gesture, the Gesture is supported since ios3.2. i can give you a simple code , you maybe modify by yourself.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    isTwoFingersBegin = NO;
    isTwoFingersEnd = NO;
    UITouch *touch = [touches anyObject];
    UIView *touchView = [touch view];
    if ([touches count] == 2)
    {
        isTwoFingersBegin = YES;
    }

    touchStartPoint = [touch locationInView:self.view];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    isSwip = YES;
}
#define TOUCH_MOVE_EFFECT_DIST 30
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{   
    UITouch *touch = [touches anyObject];
    UIView *touchView = [touch view];
    touchEndPoint = [touch locationInView:self.view];
    if ([touches count] == 2)
    {
        isTwoFingersEnd = YES;
    }
    CGPoint deltaVector = CGPointMake(touchEndPoint.x - touchStartPoint.x, touchEndPoint.y - touchStartPoint.y);

    if (fabsf(deltaVector.x) > TOUCH_MOVE_EFFECT_DIST
                &&fabsf(deltaVector.y) > TOUCH_MOVE_EFFECT_DIST
                && isSwip &&isTwoFingersBegin&&isTwoFingersEnd) {
                theSwipGesture=RightUpGesture;
            }
    else if (fabsf(deltaVector.x) <- TOUCH_MOVE_EFFECT_DIST
                && fabsf(deltaVector.y) <- TOUCH_MOVE_EFFECT_DIST
                && isSwip&&isTwoFingersBegin&&isTwoFingersEnd) {
                theSwipGesture=LeftDownGesture;
            }

    isSwip = NO;
}
Eraeradiate answered 29/7, 2012 at 7:0 Comment(0)
S
1

You need to subclass it to use touchesBegan and touchesMoved anyway. I'd do UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionLeft like you said, then set up two CGRects, one for acceptable starting points, one for acceptable end points. Then use the UIGestureRecognizerDelegate method gestureRecognizer:shouldReceiveTouch:, and check if the touch point is in the acceptable start rect by using CGRectContainsPoint(). Then (I think) in your UISwipeGestureRecognizer subclass, override touchesEnded:withEvent:, and check if the end touch is in the acceptable rect. If it's not, set the state to UIGestureRecognizerStateCancelled (or however you're supposed to cancel a gesture). Also make sure the view it's attached to has its multipleTouchEnabled property set. I haven't actually tried this, but something of the sort should do it. Good luck!

EDIT

Actually, if you didn't want to have to worry about specific rect values for the acceptable start/end points, and make it device independent, you could do this:

//swap in whatever percentage of the screen's width/height you want in place of ".75f"

//set the origin for acceptable start points
CGFloat startRect_x = self.view.frame.size.width * .75f;
CGFloat startRect_y = self.view.frame.size.height * .75f;

//set the size
CGFloat rectWidth = self.view.frame.size.width - startRect_x;
CGFloat rectHeight = self.view.frame.size.height - startRect_y;

//make the acceptable start point rect
CGRect startRect = CGRectMake(startRect_x, startRect_y, rectWidth, rectHeight);

//set the origin for the accepable end points
CGFloat endRect_x = self.view.center.x - rectWidth/2;
CGFloat endRect_y = self.view.center.y - rectHeight/2;

//make the acceptable end point rect
CGRect endRect = CGRectMake(endRect_x, endRect_y, rectWidth, rectHeight);
Solve answered 29/7, 2012 at 7:1 Comment(0)
C
1

You can use a UIPanGestureRecognizer

- (void)viewPanned:(UIPanGestureRecognizer *)panGR
{
    CGPoint translation = [panGR translationInView:self];

    CGFloat threshold = self.bounds.size.width/2;

    // Detect
    Direction direction = DirectionUnknown;

    if (translation.x > threshold) {
        if (translation.y > threshold) {
            direction = DirectionBottomRight;
        } else if (translation.y < -threshold) {
            direction = DirectionTopRight;
        } else {
            direction = DirectionRight;
        }
    } else if (translation.x < -threshold) {
        if (translation.y > threshold) {
            direction = DirectionBottomLeft;
        } else if (translation.y < -threshold) {
            direction = DirectionTopLeft;
        } else {
            direction = DirectionLeft;
        }
    } else {
        if (translation.y > threshold) {
            direction = DirectionBottom;
        } else if (translation.y < -threshold) {
            direction = DirectionTop;
        }
    }
}
Copyread answered 25/11, 2014 at 15:3 Comment(0)
T
0

One possible solution would be to map off a group of coordinates on the iPhone's screen where the swipe could potentially start, and another where it could potentially end. Then in the touchesBegan: and touchesMoved: methods, you could compare the starting and ending points of the swipe and determine whether it qualified as diagonal.

Transistor answered 29/7, 2012 at 6:58 Comment(0)
B
0

Thanks Guys!

I ended up writing custom code in touchesBegan, touchesMoved and touchesEnded and ot works like charm.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    if ([touches count] == 2) {
        CGPoint nowPoint = [[touches anyObject] locationInView:self];
        if( nowPoint.x >= ALLOWED_X)
            swipeUp = YES;
    }

    [super touchesBegan:touches withEvent:event];
}


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

    if ([touches count] == 2 && swipeUp) {

        CGPoint nowPoint = [[touches anyObject] locationInView:self];
        CGPoint prevPoint = [[touches anyObject] previousLocationInView:self];

        if( nowPoint.x <= prevPoint.x && nowPoint.y <= prevPoint.y){
        }
        else {
            swipeUp = NO;
        }
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    CGPoint nowPoint = [[touches anyObject] locationInView:self];

    if ([touches count] == 2 && swipeUp && nowPoint.x <= DELTA_X && nowPoint.y <= DELTA_Y) {
        NSLog(@"Invoke Method");
    }
    swipeUp = NO;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    swipeUp = NO;
}
Benedetto answered 29/7, 2012 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.