在IOS系统3.2过后apple公司提供了一个抽象类,UIGestureRecognizer类用于手势识别,它的子类有主要有六个分别是:
UITapGestureRecognizer(轻击一下)
UIPinchGestureRecognizer(两指控制的缩放)
UIRotationGestureRecognizer(旋转)
UISwipeGestureRecognizer(滑动,快速移动)
UIPanGestureRecognizer(拖移,慢慢移动)
UILongPressGestureRecognizer(长按)
继承关系如下:
手势的使用
1.创建手势的实例。当创建手势时,指定一个回调方法,当手势开始,改变、或结束时,回调方法被调用。
2.将实例添加到需要识别的view中,每个手势只对应一个view,但每个view可对应多个手势,当手势发生在view 边界内时,回调方法。
在虚拟机上调试时有可能会不灵敏,因此尽量在真机上运行,尤其是多指手势。
******************************************可耻的分割线********************************************************
UITapGestureRecognizer使用
UITapGestureRecognizer *tap = [
[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(huidiaohanshu:)];
[self.view addGestureRecognizer:tap];
以上内容添加到viewcontroller里面的viewDidLoad函数中,然后再定义huidiaohanshu参数就是tap,
如下
-(void)huidiaohanshu:(UITapGestureRecognizer *)tap
{
//使用手势你想要达到的效果
}
******************************************可耻的分割线********************************************************
UIPinchGestureRecognizer使用
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(huidiaohanshu:)];
[self.view addGestureRecognizer:pinch];
以上内容添加到viewcontroller里面的viewDidLoad函数中,然后再定义huidiaohanshu参数就是pinch,
如下
-(void)huidiaohanshu:(UIPinchGestureRecognizer *)
{
scale = pinchGestureRecognizer.scale;
[self transformImageView];
if (pinchGestureRecognizer.state == UIGestureRecognizerStated)
{
previousScale == scale*previousScale;
scale = 1;
}
}
其中scale和previousScale是预先定义好的实例变量,scale代表当前的缩放比例,previousScale代表先前的缩放比例。
******************************************可耻的分割线********************************************************
UIRotationGestureRecognizer使用
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(huidiaohanshu:)];
[self.view addGestureRecognizer:rotation];
以上内容添加到viewcontroller里面的viewDidLoad函数中,然后再定义huidiaohanshu参数就是rotation,
如下
-(void)huidiaohanshu:(UIRotationGestureRecognizer *)rotation
{
rotation = rotationGestureRecognizer.rotation;
[self transformImageView];
if(rotationGestureRecognizer.state == UIGestureRecognizerStateEnded)
{
previousrotation = rotation+prevoiusrotation;
rotation = 0;
}
}
其中rotation和previousrotation是预先定义好的实例变量,rotation代表当前的缩放比例,previousrotation代表先前的缩放比例。
******************************************可耻的分割线********************************************************
UISwipeGestureRecognizer的使用
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(huidiaohanshu:)];
swipe.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;//如果需要横向的就用Left | Right
[self.view addGestureRecognizer:swipe];
以上内容添加到viewcontroller里面的viewDidLoad函数中,然后再定义huidiaohanshu参数就是swipe如下
-(void)huidiaohanshu:(UISwipeGestureRecognizer *)swipe
{
//使用手势所要达到的效果
}
******************************************可耻的分割线********************************************************
UIPanGestureRecognizer的使用
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(huidiaohanshu:)];
[self.view addGestureRecognizer:pan];
以上内容添加到viewcontroller里面的viewDidLoad函数中,然后再定义huidiaohanshu参数就是pan,
如下
-(void)huidiaohanshu:(UIPanGestureRecognizer *)panGestureRecognize
{
//使用手势所要达到的效果
CGPoint translation = [panGestureRecognize translationInView:self.view];
panGestureRecognize.view.center = CGPointMake(panGestureRecognize.view.center.x + translation.x,
panGestureRecognize.view.center.y + translation.y);
[panGestureRecognize setTranslation:CGPointZero inView:self.view];
if (panGestureRecognize.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [panGestureRecognize velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(panGestureRecognize.view.center.x + (velocity.x * slideFactor),
panGestureRecognize.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
panGestureRecognize.view.center = finalPoint;
} completion:nil];
}
以上代码解析:
- 计算速度向量的长度(估计大部分都忘了)这些知识了。
- 如果速度向量小于200,那就会得到一个小于的小数,那么滑行会很短
- 基于速度和速度因素计算一个终点
- 确保终点不会跑出父View的边界
- 使用UIView动画使view滑动到终点
******************************************可耻的分割线********************************************************
UILongPressGestureRecognizer的使用
UILongPressGestureRecognizer *longpress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(huidiaohanshu:)];
longpress.minimumPressDuration = 1.0;
[self.view addGestureRecognizer:longpress];
以上内容添加到viewcontroller里面的viewDidLoad函数中,然后再定义huidiaohanshu参数就是longpress如下
-(void)huidiaohanshu:(UILongPressGestureRecognizer *)longpress
{
if(longpress.state == UIGestureRecognizerStateBegan)
{
CGPoint point = [longpress locationInView:self.tableView];
if(indexPath == nil)
return;
//使用手势所要达到的效果
}
}
******************************************可耻的分割线********************************************************
自定义手势
继承UIGestureRecognizer,并实现以下方法
-touchesBegan:withEvent:
-touchesMoved:withEvent:
-touchesEnded:withEvent:
-touchesCancelled:withEvent:
具体如下:
新建一个类,继承UIGestureRecognizer,代码如下:
.h文件
************************************************************
#import
typedef enum {
DirectionUnknown = 0,
DirectionLeft,
DirectionRight
} Direction;
@interface HappyGestureRecognizer : UIGestureRecognizer
@property (assign) int tickleCount;
@property (assign) CGPoint curTickleStart;
@property (assign) Direction lastDirection;
@end
************************************************************************
.m文件
**************************************************************************************
#import "HappyGestureRecognizer.h"
#import
#define REQUIRED_TICKLES 2
#define MOVE_AMT_PER_TICKLE 25
@implementation HappyGestureRecognizer
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
self.curTickleStart = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// Make sure we've moved a minimum amount since curTickleStart
UITouch * touch = [touches anyObject];
CGPoint ticklePoint = [touch locationInView:self.view];
CGFloat moveAmt = ticklePoint.x - self.curTickleStart.x;
Direction curDirection;
if (moveAmt < 0) {
curDirection = DirectionLeft;
} else {
curDirection = DirectionRight;
}
if (ABS(moveAmt) < MOVE_AMT_PER_TICKLE) return;
// 确认方向改变了
if (self.lastDirection == DirectionUnknown ||
(self.lastDirection == DirectionLeft && curDirection == DirectionRight) ||
(self.lastDirection == DirectionRight && curDirection == DirectionLeft)) {
// 挠痒次数
self.tickleCount++;
self.curTickleStart = ticklePoint;
self.lastDirection = curDirection;
// 一旦挠痒次数超过指定数,设置手势为结束状态
// 这样回调函数会被调用。
if (self.state == UIGestureRecognizerStatePossible && self.tickleCount > REQUIRED_TICKLES) {
[self setState:UIGestureRecognizerStateEnded];
}
}
}
- (void)reset {
self.tickleCount = 0;
self.curTickleStart = CGPointZero;
self.lastDirection = DirectionUnknown;
if (self.state == UIGestureRecognizerStatePossible) {
[self setState:UIGestureRecognizerStateFailed];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self reset];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self reset];
}
@end
**************************************************************************************
调用自定义手势和以前一样
HappyGestureRecognizer *happy = [[HappyGestureRecognizer alloc]initWithTarget:self action:@selector(handleHappy:)];
[self.view addGestureRecognizer:happy];
回调函数
-(void)handleHappy:(HappyGestureRecognizer *)happy
{
//所要达到的效果
}
资料来源:http://blog.youkuaiyun.com/totogo2010/article/details/8615940
http://www.cnblogs.com/salam/archive/2013/04/30/iOS_gesture.html
http://mobile.51cto.com/iphone-403791.htm
精通IOS开发(第五版)David Mark Jack Nutting 等著