Swipe detection in any angle

烂漫一生 提交于 2019-12-06 03:23:30

问题


Is there any way I can detect swipe in iPhone in any angle? UISwipeGestureRecognizer seems to have only 4 directions.
If I swipe like this:

\
 \
  \
   X

I want it to give me something like 60 degrees and not just down like the UISwipeGestureRecognizer.
How can I do this?


回答1:


You can use a UIPanGestureRecognizer. When you detect the Ended state you can get the velocity. The velocity is broken into x and y components. You can use the x and y components to calculate the slope, m.

m = ∆y / ∆x

The angle of the line, 𝛳, defined by the slope, m, relative to the x axis is defined by:

𝛳 = arctan(m)

Something like:

- (void)didPan:(UIPanGestureRecognizer*)recognizer {
    switch (recognizer.state) {
        case UIGestureRecognizerStateBegan:
            ...
            break;

        case UIGestureRecognizerStateEnded:
            CGPoint velocity = [recognizer velocityInView:[recognizer.view superview]];
            // If needed: CGFloat slope = velocity.y / velocity.x;
            CGFloat angle = atan2f(velocity.y, velocity.x);
            ...
            break;
    }
}



回答2:


You can just detect the start and stop of the touch and calculate the angle with the two points.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//global CGPoint.
    //this should be it's GLOBAL coordinates, not just relative to the view    
    startPoint=[[touches anyObject] locationInView:self.superview.superview];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    //global CGPoint
    endPoint=[[touches anyObject] locationInView:self.superview.superview];
}

To calculate the angle between them you could use something like this:

static inline CGFloat angleBetweenLinesInRadians(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {

    CGFloat a = line1End.x - line1Start.x;
    CGFloat b = line1End.y - line1Start.y;
    CGFloat c = line2End.x - line2Start.x;
    CGFloat d = line2End.y - line2Start.y;

    CGFloat line1Slope = (line1End.y - line1Start.y) / (line1End.x - line1Start.x);
    CGFloat line2Slope = (line2End.y - line2Start.y) / (line2End.x - line2Start.x);

    CGFloat degs = acosf(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
    return (line2Slope > line1Slope) ? degs : -degs;    
}
//This code came from someone else and I don't remember who to give credit to.

So to find the angle off of a horizontal line you could do something like this

CGFloat angle=angleBetweenLinesInRadians(startPoint, endPoint, startPoint, CGPointMake(startPoint.x + 10, startPoint.y));

That would be the angle like so

________
\ this angle
 \
  \
   x

Hope this helps

EDIT a better way

What you can do is subclass UIGestureRecognizer

#import <UIKit/UIGestureRecognizerSubclass.h>

You then implement these methods

- (void)reset;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

Each of these is used to determine and set the state property for the gesture.

There is a full example here: http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizers/GestureRecognizers.html



来源:https://stackoverflow.com/questions/7863265/swipe-detection-in-any-angle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!