【发布时间】:2011-10-22 23:20:14
【问题描述】:
有什么方法可以检测到 iPhone 中任何角度的滑动? UISwipeGestureRecognizer 似乎只有 4 个方向。
如果我这样滑动:
\
\
\
X
我希望它能给我带来 60 度的温度,而不是像 UISwipeGestureRecognizer 那样向下倾斜。
我该怎么做?
【问题讨论】:
有什么方法可以检测到 iPhone 中任何角度的滑动? UISwipeGestureRecognizer 似乎只有 4 个方向。
如果我这样滑动:
\
\
\
X
我希望它能给我带来 60 度的温度,而不是像 UISwipeGestureRecognizer 那样向下倾斜。
我该怎么做?
【问题讨论】:
您可以使用UIPanGestureRecognizer。当您检测到 Ended 状态时,您可以获得速度。速度分为 x 和 y 分量。您可以使用 x 和 y 分量来计算斜率 m。
m = Δy / Δx
由斜率 m 定义的直线的角度 ? 相对于 x 轴的定义如下:
? = arctan(m)
类似:
- (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;
}
}
【讨论】:
您可以只检测触摸的开始和停止,并计算两个点的角度。
-(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];
}
要计算它们之间的角度,您可以使用以下方法:
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.
所以要找到水平线的角度,你可以这样做
CGFloat angle=angleBetweenLinesInRadians(startPoint, endPoint, startPoint, CGPointMake(startPoint.x + 10, startPoint.y));
应该是这样的角度
________
\ this angle
\
\
x
希望对你有帮助
编辑更好的方法
你可以做的是子类 UIGestureRecognizer
#import <UIKit/UIGestureRecognizerSubclass.h>
然后你实现这些方法
- (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;
每一个都用于确定和设置手势的状态属性。
【讨论】:
atan2(deltaY, deltaX) 为您提供象限和水平/垂直考虑的角度。