iOS 手势UIGestureRecognizer

在 iPhone 或 iPad 的开发中,除了用 touchesBegan / touchesMoved / touchesEnded 这组方法来控制使用者的手指触控外,也可以用 UIGestureRecognizer 的衍生类別来进行判断。用 UIGestureRecognizer 的好处在于有现成的手势,开发者不用自己计算手指移动轨迹。UIGestureRecognizer的衍生类別有以下几种:

UITapGestureRecognizer

UIPinchGestureRecognizer

UIRotationGestureRecognizer

UISwipeGestureRecognizer

UIPanGestureRecognizer

UILongPressGestureRecognizer

从命名上不难了解這些类別所对应代表的手势,分別是 Tap(点一下)、Pinch(二指往內或往外拨动)、Rotation(旋转)、Swipe(滑动,快速移动)、Pan (拖移,慢速移动)以及 LongPress(长按)。這些手势別在使用上也很简单,只要在使用前定义并添加到对应的视图上即可。

复制代码

// 定义一个 recognizer, 并加到需要偵測该手势的 UIView 元件上

- (void)viewDidLoad {

UISwipeGestureRecognizer* recognizer;

// handleSwipeFrom 是偵測到手势,所要呼叫的方法

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSwipeFrom)];

// 不同的 Recognizer 有不同的实体变数

// 例如 SwipeGesture 可以指定方向

// 而 TapGesture 則可以指定次數

recognizer.direction = UISwipeGestureRecognizerDirectionUp

[self.view addGestureRecognizer:recognizer];

[recognizer release];

}

- (void)handleSwipeFrom:(UISwipeGestureRecognizer*)recognizer {

// 触发手勢事件后,在这里作些事情

// 底下是刪除手势的方法

[self.view removeGestureRecognizer:recognizer];

}

复制代码

问题來了。有些手势其实是互相关联的,例如 Tap 与 LongPress、Swipe与 Pan,或是 Tap 一次与Tap 兩次。当一個 UIView 同时添加兩个相关联的手势时,到底我这一下手指头按的要算是 Tap 还是 LongPress?如果照預设作法来看,只要「先滿足条件」的就会跳出并呼叫对应方法,举例来说,如果同时注册了 Pan 和 Swipe,只要手指头一移动就会触发 Pan 然后跳出,因而永远都不會发生 Swipe;单点与双点的情形也是一样,永远都只会触发单点,不會有双点。

那么这个问题有解吗?答案是肯定的,UIGestureRecognizer 有个方法叫做requireGestureRecognizerToFail,他可以指定某一个 recognizer,即便自己已经滿足條件了,也不會立刻触发,会等到该指定的 recognizer 确定失败之后才触发。以同时支持单点与双点的手势为例,代码如下:

复制代码

- (void)viewDidLoad {

// 单击的 Recognizer

UITapGestureRecognizer* singleRecognizer;

singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSingleTapFrom)];

singleTapRecognizer.numberOfTapsRequired = 1; // 单击

[self.view addGestureRecognizer:singleRecognizer];

// 双击的 Recognizer

UITapGestureRecognizer* double;

doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleDoubleTapFrom)];

doubleTapRecognizer.numberOfTapsRequired = 2; // 双击

[self.view addGestureRecognizer:doubleRecognizer];

// 关键在这一行,如果双击确定偵測失败才會触发单击

[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];

[singleRecognizer release];

[doubleRecognizer release];

}

Demo

首先新建一个基于Sigle view Application的项目,名为GestureTest;我的项目结构如下:

往viewController.xib文件里拖动一个imageView,并使覆盖整个屏幕,改动属性为:

viewController.h文件:

1.     #import <UIKit/UIKit.h>

2.

3.     @interface ViewController : UIViewController{

4.         IBOutlet UIImageView *imageView;

5.     }

6.     @property (nonatomic,retain)IBOutlet UIImageView *imageView;

7.     @end

并使xib文件里的imageView与之连接;

然后是viewController.m文件的实现部分:

1.     @synthesize imageView;

2.

3.     CGFloat lastScaleFactor=1;//放大、缩小

4.     CGFloat  netRotation;//旋转

5.     CGPoint netTranslation;//平衡

6.     NSArray *images;//图片数组

7.     int imageIndex=0;//数组下标

8.

9.     - (void)viewDidLoad

10.   {

11.       //1、创建手势实例,并连接方法handleTapGesture,点击手势

12.       UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTapGesture:)];

13.       //设置手势点击数,双击:点2下

14.       tapGesture.numberOfTapsRequired=2;

15.       // imageView添加手势识别

16.       [imageView addGestureRecognizer:tapGesture];

17.       //释放内存

18.       [tapGesture release];

19.

20.       //2、手势为捏的姿势:按住option按钮配合鼠标来做这个动作在虚拟器上

21.       UIPinchGestureRecognizer *pinchGesture=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinchGesture:)];

22.       [imageView addGestureRecognizer:pinchGesture];//imageView添加手势识别

23.       [pinchGesture release];

24.

25.       //3、旋转手势:按住option按钮配合鼠标来做这个动作在虚拟器上

26.       UIRotationGestureRecognizer *rotateGesture=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(handleRotateGesture:)];

27.       [imageView addGestureRecognizer:rotateGesture];

28.       [rotateGesture release];

29.

30.       //4、拖手势

31.       UIPanGestureRecognizer *panGesture=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGesture:)];

32.      // [imageView addGestureRecognizer:panGesture];

33.       [panGesture release];

34.

35.       //5、划动手势

36.       images=[[NSArray alloc]initWithObjects:@"cell.jpg",@"heihua.jpg",@"xuanyi.jpg", nil];

37.       //右划

38.       UISwipeGestureRecognizer *swipeGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];

39.       [imageView addGestureRecognizer:swipeGesture];

40.       [swipeGesture release];

41.       //左划

42.       UISwipeGestureRecognizer *swipeLeftGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];

43.       swipeGesture.direction=UISwipeGestureRecognizerDirectionLeft;//不设置黑夜是右

44.       [imageView addGestureRecognizer:swipeLeftGesture];

45.       [swipeLeftGesture release];

46.

47.       //6、长按手势

48.       UILongPressGestureRecognizer *longpressGesutre=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongpressGesture:)];

49.       //长按时间为1秒

50.       longpressGesutre.minimumPressDuration=1;

51.       //允许15秒中运动

52.       longpressGesutre.allowableMovement=15;

53.       //所需触摸1次

54.       longpressGesutre.numberOfTouchesRequired=1;

55.       [imageView addGestureRecognizer:longpressGesutre];

56.       [longpressGesutre release];

57.

58.       [super viewDidLoad];

59.       // Do any additional setup after loading the view, typically from a nib.

60.   }

61.   //双击屏幕时会调用此方法,放大和缩小图片

62.   -(IBAction)handleTapGesture:(UIGestureRecognizer*)sender{

63.       //判断imageView的内容模式是否是UIViewContentModeScaleAspectFit,该模式是原比例,按照图片原时比例显示大小

64.       if(sender.view.contentMode==UIViewContentModeScaleAspectFit){

65.           //把imageView模式改成UIViewContentModeCenter,按照图片原先的大小显示中心的一部分在imageView

66.           sender.view.contentMode=UIViewContentModeCenter;

67.       }else{

68.           sender.view.contentMode=UIViewContentModeScaleAspectFit;

69.       }

70.   }

71.   //捏的手势,使图片放大和缩小,捏的动作是一个连续的动作

72.   -(IBAction)handlePinchGesture:(UIGestureRecognizer*)sender{

73.       //得到sender捏手势的大小

74.       CGFloat factor=[(UIPinchGestureRecognizer*)sender scale];

75.       if(factor>1){

76.           //图片放大

77.           sender.view.transform=CGAffineTransformMakeScale(lastScaleFactor+(factor-1), (lastScaleFactor+(factor-1)));

78.

79.       }else{

80.           //缩小

81.           sender.view.transform=CGAffineTransformMakeScale(lastScaleFactor*factor, lastScaleFactor*factor);

82.

83.       }

84.       //状态是否结束,如果结束保存数据

85.       if(sender.state==UIGestureRecognizerStateEnded){

86.           if(factor>1){

87.               lastScaleFactor+=(factor-1);

88.           }else{

89.               lastScaleFactor*=factor;

90.           }

91.       }

92.   }

93.   //旋转手势

94.   -(IBAction)handleRotateGesture:(UIGestureRecognizer*)sender{

95.       //浮点类型,得到sender的旋转度数

96.       CGFloat rotation=[(UIRotationGestureRecognizer*)sender rotation];

97.       //旋转角度CGAffineTransformMakeRotation

98.       CGAffineTransform transform=CGAffineTransformMakeRotation(rotation+netRotation);

99.       //改变图像角度

100.      sender.view.transform=transform;

101.      //状态结束,保存数据

102.      if(sender.state==UIGestureRecognizerStateEnded){

103.          netRotation+=rotation;

104.      }

105.

106.  }

107.  //拖手势

108.  -(IBAction)handlePanGesture:(UIGestureRecognizer*)sender{

109.      //得到拖的过程中的xy坐标

110.      CGPoint translation=[(UIPanGestureRecognizer*)sender translationInView:imageView];

111.      //平移图片CGAffineTransformMakeTranslation

112.      sender.view.transform=CGAffineTransformMakeTranslation(netTranslation.x+translation.x, netTranslation.y+translation.y);

113.      //状态结束,保存数据

114.      if(sender.state==UIGestureRecognizerStateEnded){

115.          netTranslation.x+=translation.x;

116.          netTranslation.y+=translation.y;

117.      }

118.

119.  }

120.  //划动手势

121.  -(IBAction)handleSwipeGesture:(UIGestureRecognizer*)sender{

122.      //划动的方向

123.      UISwipeGestureRecognizerDirection direction=[(UISwipeGestureRecognizer*) sender direction];

124.      //判断是上下左右

125.      switch (direction) {

126.          case UISwipeGestureRecognizerDirectionUp:

127.              NSLog(@"up");

128.              break;

129.          case UISwipeGestureRecognizerDirectionDown:

130.              NSLog(@"down");

131.              break;

132.          case UISwipeGestureRecognizerDirectionLeft:

133.              NSLog(@"left");

134.              imageIndex++;//下标++

135.              break;

136.          case UISwipeGestureRecognizerDirectionRight:

137.              NSLog(@"right");

138.              imageIndex--;//下标--

139.              break;

140.          default:

141.              break;

142.      }

143.      //得到不越界不<0的下标

144.      imageIndex=(imageIndex<0)?([images count]-1):imageIndex%[images count];

145.      //imageView显示图片

146.      imageView.image=[UIImage imageNamed:[images objectAtIndex:imageIndex]];

147.

148.  }

149.  //长按手势

150.  -(IBAction)handleLongpressGesture:(UIGestureRecognizer*)sender{

151.      //创建警告

152.      UIActionSheet *actionSheet=[[UIActionSheet alloc]initWithTitle:@"Image options" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:@"Save Image",@"Copy", nil];

153.      //当前view显示警告

154.      [actionSheet showInView:self.view];

155.      [actionSheet release];

156.  }

157.  -(void)dealloc{

158.      [images release];

159.      [imageView release];

160.      [super dealloc];

161.  }

时间: 2024-08-01 16:11:12

iOS 手势UIGestureRecognizer的相关文章

iOS手势UIGestureRecognizer

UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,它有6个子类处理具体的手势: 1.UITapGestureRecognizer (任意手指任意次数的点击) // 点击次数 numberOfTapsRequired // 手指个数 numberOfTouchesRequired [plain] view plaincopy UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer a

iOS手势UIGestureRecognizer识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) (转)

1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了UIGestureRecognizer类.手势识别UIGestureRecognizer类是个抽象类,下面的子类是具体的手势,开发这可以直接使用这些手势识别. UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecog

iOS手势学习UIGestureRecognizer &amp; cocos2d 手势推荐

iOS手势学习UIGestureRecognizer & cocos2d 手势推荐 手势识别类型: UILongPressGestureRecognizer  // 长按UIPanGestureRecognizer  // 慢速拖动UIPinchGestureRecognizer  // 两指向內或向外拨动UIRotationGestureRecognizer   // 旋转UISwipeGestureRecognizer   // 快速滑动UITapGestureRecognizer   //

IOS开发之手势—UIGestureRecognizer 共存

IOS开发之手势--UIGestureRecognizer 共存 在 iPhone 或 iPad 的开发中,除了用 touchesBegan / touchesMoved / touchesEnded 这组方法来控制使用者的手指触控外,也可以用 UIGestureRecognizer 的衍生类別来进行判断.用 UIGestureRecognizer 的好处在于有现成的手势,开发者不用自己计算手指移动轨迹.UIGestureRecognizer的衍生类別有以下几种: UITapGestureRec

iOS手势 规避同一界面上不同子界面同时响应多个手势

最近在项目中遇到这样一个有关iOS手势的问题,首先需求描述如下:“在一个CollectionView中,要求长按不同的cell,产生一个cell的snapshot,此时可拖拽这个snapshot再进行后续的操作(如拖到view的某个位置出发一个事件)”.需求本身并不复杂,但要求每次只能有一个cell响应长按手势,不允许同时有两个或以上的cell响应长按手势. 我们知道UIGestureRecognizer有很多回调和方法可以兼容同一个View上的多种手势,网上相关的教程也很多,比如: http:

iOS 手势冲突

UITableView以及ScrollView不能相迎TouchBegin处理 IOS开发之手势--UIGestureRecognizer 共存 // 关键在这一行,如果双击确定偵測失败才會触发单击 [singleRecognizer requireGestureRecognizerToFail:doubleRecognizer]; 关于UIScrollView不能响应UITouch事件的解决办法 覆盖touch事件 ios的手势操作之UIGestureRecognizer浅析 UITapGes

iOS 手势识别器概述

手势识别器 iOS 手势识别器(UIGestureRecognizer) 点击手势(UITapGestureRecognizer) 滑动手势(UISwipeGestureRecognizer) 旋转手势(UIRotationGestureRecognizer) 捏合手势( UIPinchGestureRecognizer) 长按手势( UILongPressGestureRecognizer) 平移手势( UIPanGestureRecognizer) 屏幕边缘平移手势(UIScreenEdge

iOS手势处理

iOS手势处理 iOS手势有着如下几种: UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecognizer UISwipeGestureRecognizer UIPanGestureRecognizer UILongPressGestureRecognizer 上面的手势对应的操作是: Tap          (点一下) Pinch        (二指往內或往外拨动,平时经常用到的缩放)  矩阵变换 Rot

iOS手势识别器

UIGestureRecognizer UIGestureRecognizer类,用于检测.识别用户使用设备时所用的手势.它是一个抽象类,定义了所有手势的基本行为.以下是UIGestureRecognizer子类,用于处理具体的用户手势行为: UITapGestureRecognizer // 1.单击 UILongPressGestureRecognizer // 3.长按 UISwipeGestureRecognizer // 4.轻扫 UIPanGestureRecognizer // 5