手势识别

来源:互联网 发布:婴儿和尚服品牌知乎 编辑:程序博客网 时间:2024/05/01 06:51

 

源自:http://www.yao99.com/blog/

 

轻击:

需要在你的ViewController里重写几个方法:

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

messageLabel.text = @”Touches Began”;//开始触摸的方法

[self updateLabelsFromTouches:touches];

}

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

messageLabel.text = @”Touches Cancelled”;//触摸取消的方法

[self updateLabelsFromTouches:touches];

}

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

messageLabel.text = @”Touches Stopped.”;//触摸结束的方法

[self updateLabelsFromTouches:touches];

}

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

messageLabel.text = @”Drag Detected”;//触摸移动的方法

[self updateLabelsFromTouches:touches];

}

 

 

触摸-轻扫:

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

UITouch *touch = [touches anyObject];

gestureStartPoint = [touch locationInView:self.view];//开始触摸

}

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

UITouch *touch = [touches anyObject];

CGPoint currentPosition = [touch locationInView:self.view];

CGFloat deltaX = fabsf(gestureStartPoint.x - currentPosition.x);

CGFloat deltaY = fabsf(gestureStartPoint.y - currentPosition.y);

if (deltaX >= kMinimumGestureLength && deltaY <= kMaximumVariance) {

label.text = @”Horizontal swipe detected”;

[self performSelector:@selector(eraseText) withObject:nil afterDelay:2];

}

else if (deltaY >= kMinimumGestureLength && deltaX <= kMaximumVariance){

label.text = @”Vertical swipe detected”;

[self performSelector:@selector(eraseText) withObject:nil afterDelay:2];

}

//kMinimumGestureLength 最小移动长度 kMaximumVariance 最大偏移长度

}

 

多次轻击判断,比如双击,三击等:

- (void)singleTap {

singleLabel.text = @”Single Tap Detected”;//单击动作响应事件

[self performSelector:@selector(eraseMe:) withObject:singleLabel afterDelay:1.6f];//1.6秒后执行eraseMe方法

}

- (void)doubleTap {

doubleLabel.text = @”Double Tap Detected”; //双击

[self performSelector:@selector(eraseMe:)

withObject:doubleLabel afterDelay:1.6f];

}

- (void)tripleTap {

tripleLabel.text = @”Triple Tap Detected”;    //三击

[self performSelector:@selector(eraseMe:)

withObject:tripleLabel afterDelay:1.6f];

}

- (void)quadrupleTap {

quadrupleLabel.text = @”Quadruple Tap Detected”;//四击

[self performSelector:@selector(eraseMe:)

withObject:quadrupleLabel afterDelay:1.6f];

}

- (void)eraseMe:(UITextField *)textField {

textField.text = @”";

}

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

UITouch *touch = [touches anyObject];//实例一个uitouch

NSUInteger tapCount = [touch tapCount]; //计算touch的tapCount次数

switch (tapCount) {

case 1:

[self singleTap];

break;

case 2:

[self doubleTap];

break;

case 3:

[self tripleTap];

break;

case 4:

[self quadrupleTap];

break;

default:

break;

}

}

[self performSelector:@selector(eraseMe:)withObject:singleLabel afterDelay:1.6f]中

performSelector:@selector(eraseMe:)withObject:singleLabel afterDelay:1.6f方法为将来afterDelay1.6秒之后调用eraseMe方法

同样的[NSObect  cancelPreviousPerformSelector:withObject :afterDelay:];方法为取消这些将来的调用

 

捏合操作:

- (void)eraseLabel {//清空lable

label.text = @”";

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {//开始触碰

if ([touches count] == 2) {//检测是否为两个手指触点

NSArray *twoTouches = [touches allObjects];

UITouch *first = [twoTouches objectAtIndex:0];

UITouch *second = [twoTouches objectAtIndex:1];

initialDistance = distanceBetweenPoints([first locationInView:self.view], [second locationInView:self.view]);

}

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {//移动手指

if ([touches count] == 2) {

NSArray *twoTouches = [touches allObjects];

UITouch *first = [twoTouches objectAtIndex:0];

UITouch *second = [twoTouches objectAtIndex:1];

CGFloat currentDistance = distanceBetweenPoints([first locationInView:self.view],[second locationInView:self.view]);

if (initialDistance == 0)

initialDistance = currentDistance; //根据移动前后的坐标距离差检测是捏合的手势还是打开的手势

else if (currentDistance - initialDistance > kMinimumPinchDelta) {//检测是否大于最小移动值kMinimumPinchDelta

label.text = @”Outward Pinch”;

[self performSelector:@selector(eraseLabel) withObject:nil afterDelay:1.6f];

}

else if (initialDistance - currentDistance > kMinimumPinchDelta) {

label.text = @”Inward Pinch”;

[self performSelector:@selector(eraseLabel) withObject:nil afterDelay:1.6f];

}

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {//触碰结束

initialDistance = 0;

}

 

 

自定义手势“√”:

- (void)eraseLabel {

label.text = @”";

}

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

UITouch *touch = [touches anyObject];

CGPoint point = [touch locationInView:self.view];

lastPreviousPoint = point;

lastCurrentPoint = point;

lineLengthSoFar = 0.0f;

}

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

UITouch *touch = [touches anyObject];

CGPoint previousPoint = [touch previousLocationInView:self.view];

CGPoint currentPoint = [touch locationInView:self.view];

CGFloat angle = angleBetweenLines(lastPreviousPoint, //计算两条线之间的角度

lastCurrentPoint,

previousPoint,

currentPoint);

if (angle >= kMinimumCheckMarkAngle&& angle <= kMaximumCheckMarkAngle

&& lineLengthSoFar > kMinimumCheckMarkLength) {//检测手势被承认的条件 kMinimumCheckMarkAngle 最小角度kMaximumCheckMarkAngle最大角度kMinimumCheckMarkLength 画线最小长度

label.text = @”Checkmark”;

[self performSelector:@selector(eraseLabel) withObject:nil afterDelay:1.6];

}

lineLengthSoFar += distanceBetweenPoints(previousPoint, currentPoint);//lineLengthSoFar //lastPreviousPoint, lastCurrentPoint 重新赋值

lastPreviousPoint = previousPoint;

lastCurrentPoint = currentPoint;

}

 

这里用到一个判断两条直线的角度的方法 

angleBetweenLines(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPointlin2End);

 

给一个几何方法集的接口方法:

CGPointUtils.h 头文件

#import <CoreGraphics/CoreGraphics.h>

CGFloat distanceBetweenPoints (CGPoint first, CGPoint second);

CGFloat angleBetweenPoints(CGPoint first, CGPoint second);

CGFloat angleBetweenLines(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint lin2End);

.c文件 CGPointUtils.c

#include ”CGPointUtils.h”

#include <math.h>

#define pi 3.14159265358979323846

#define degreesToRadian(x) (pi * x / 180.0)

#define radiansToDegrees(x) (180.0 * x / pi)

CGFloat distanceBetweenPoints (CGPoint first, CGPoint second) {

CGFloat deltaX = second.x - first.x;

CGFloat deltaY = second.y - first.y;

return sqrt(deltaX*deltaX + deltaY*deltaY );

};

 

CGFloat angleBetweenPoints(CGPoint first, CGPoint second) {

CGFloat height = second.y - first.y;

CGFloat width = first.x - second.x;

CGFloat rads = atan(height/width);

return radiansToDegrees(rads);

//degs = degrees(atan((top – bottom)/(right – left)))

}

 

CGFloat angleBetweenLines(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 rads = acos(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));

return radiansToDegrees(rads);

}

把他加到工程里 在需要的地方#import ”CGPointUtils.h” 就可以直接用了

 

原创粉丝点击