天天看點

UIGestureRecognizer 6種手勢用法介紹

UIGestureRecognizer 是一個具體手勢的基類,提供了較為簡單的手勢實作方式  

The concrete subclasses of 

UIGestureRecognizer

 are the following:

  • UITapGestureRecognizer

  • UIPinchGestureRecognizer

  • UIRotationGestureRecognizer

  • UISwipeGestureRecognizer

  • UIPanGestureRecognizer

  • UILongPressGestureRecognizer

一個gesture recognizer是針對一個特定的view的(包含其subview),用UIView的方法addGestureRecognize:去關聯一個view

一個gesture recognizer是不參與UIView的事件響應鍊的

各個手勢使用時的代碼:

UITapGestureRecognizer

[cpp]  view plain  copy

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view from its nib.  
  5.     UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  6.     if (![tapGesture respondsToSelector:@selector(locationInView:)]) {  
  7.         [tapGesture release];  
  8.         tapGesture = nil;  
  9.     }else {  
  10.         tapGesture.delegate = self;  
  11.         tapGesture.numberOfTapsRequired = 1; // The default value is 1.  
  12.         tapGesture.numberOfTouchesRequired = 1; // The default value is 1.  
  13.         [self.view addGestureRecognizer:tapGesture];  
  14.     }  
  15. }  

[cpp]  view plain  copy

  1. - (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer  
  2. {  
  3.     UIView *view = [gestureRecognizer view]; // 這個view是手勢所屬的view,也就是增加手勢的那個view  
  4.     switch (gestureRecognizer.state) {  
  5.         case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 正常情況下隻響應這個消息  
  6.             NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");  
  7.             break;  
  8.         }  
  9.         case UIGestureRecognizerStateFailed:{ //   
  10.             NSLog(@"======UIGestureRecognizerStateFailed");  
  11.             break;  
  12.         }  
  13.         case UIGestureRecognizerStatePossible:{ //   
  14.             NSLog(@"======UIGestureRecognizerStatePossible");  
  15.             break;  
  16.         }  
  17.         default:{  
  18.             NSLog(@"======Unknow gestureRecognizer");  
  19.             break;  
  20.         }  
  21.     }    
  22. }  
  23. // 詢問一個手勢接收者是否應該開始解釋執行一個觸摸接收事件  
  24. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{  
  25. //    CGPoint currentPoint = [gestureRecognizer locationInView:self.view];  
  26. //    if (CGRectContainsPoint(CGRectMake(0, 0, 100, 100), currentPoint) ) {  
  27. //        return YES;  
  28. //    }  
  29. //      
  30. //    return NO;  
  31.     return YES;  
  32. }  
  33. // 詢問delegate,兩個手勢是否同時接收消息,傳回YES同僚接收。傳回NO,不同是接收(如果另外一個手勢傳回YES,則并不能保證不同時接收消息)the default implementation returns NO。  
  34. // 這個函數一般在一個手勢接收者要阻止另外一個手勢接收自己的消息的時候調用  
  35. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{  
  36.     return NO;  
  37. }  
  38. // 詢問delegate是否允許手勢接收者接收一個touch對象  
  39. // 傳回YES,則允許對這個touch對象稽核,NO,則不允許。  
  40. // 這個方法在touchesBegan:withEvent:之前調用,為一個新的touch對象進行調用  
  41. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{  
  42.     return YES;  
  43. }  

UIPinchGestureRecognizer

[cpp]  view plain  copy

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view from its nib.  
  5.     UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  6.     if (![pinchGesture respondsToSelector:@selector(locationInView:)]) {  
  7.         [pinchGesture release];  
  8.         pinchGesture = nil;  
  9.     }else {  
  10.         pinchGesture.delegate = self;  
  11.         [self.view addGestureRecognizer: pinchGesture];  
  12.     }    
  13. }  
  14. - (void)handleGesture:(UIPinchGestureRecognizer *)gestureRecognizer  
  15. {  
  16.     UIView *view = [gestureRecognizer view]; // 這個view是手勢所屬的view,也就是增加手勢的那個view  
  17.     CGFloat scale = gestureRecognizer.scale;  
  18.     NSLog(@"======scale: %f", scale);  
  19.     CGFloat velocity = gestureRecognizer.velocity;  
  20.     NSLog(@"======scvelocityale: %f", velocity);  
  21.     switch (gestureRecognizer.state) {  
  22.         case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded  
  23.             NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");  
  24.             break;  
  25.         }  
  26.         case UIGestureRecognizerStateBegan:{ //   
  27.             NSLog(@"======UIGestureRecognizerStateBegan");  
  28.             break;  
  29.         }  
  30.         case UIGestureRecognizerStateChanged:{ //   
  31.             NSLog(@"======UIGestureRecognizerStateChanged");  
  32.             gestureRecognizer.view.transform = CGAffineTransformScale(gestureRecognizer.view.transform, gestureRecognizer.scale, gestureRecognizer.scale);  
  33.             gestureRecognizer.scale = 1; // 重置,很重要!!!  
  34.             break;  
  35.         }  
  36.         case UIGestureRecognizerStateCancelled:{ //   
  37.             NSLog(@"======UIGestureRecognizerStateCancelled");  
  38.             break;  
  39.         }  
  40.         case UIGestureRecognizerStateFailed:{ //   
  41.             NSLog(@"======UIGestureRecognizerStateFailed");  
  42.             break;  
  43.         }  
  44.         case UIGestureRecognizerStatePossible:{ //   
  45.             NSLog(@"======UIGestureRecognizerStatePossible");  
  46.             break;  
  47.         }  
  48.         default:{  
  49.             NSLog(@"======Unknow gestureRecognizer");  
  50.             break;  
  51.         }  
  52.     }    
  53. }  

UIRotationGestureRecognizer

[cpp]  view plain  copy

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view from its nib.  
  5.     UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  6.     if (![rotationGesture respondsToSelector:@selector(locationInView:)]) {  
  7.         [rotationGesture release];  
  8.         rotationGesture = nil;  
  9.     }else {  
  10.         rotationGesture.delegate = self;  
  11.         [self.view addGestureRecognizer:rotationGesture];  
  12.     }  
  13. }  
  14. - (void)handleGesture:(UIRotationGestureRecognizer *)gestureRecognizer  
  15. {  
  16.     UIView *view = [gestureRecognizer view]; // 這個view是手勢所屬的view,也就是增加手勢的那個view  
  17.     CGFloat rotation = gestureRecognizer.rotation;  
  18.     NSLog(@"===rotation: %f", rotation);  
  19.     CGFloat velocity = gestureRecognizer.velocity;  
  20.     NSLog(@"======velocity: %f", velocity);  
  21.     switch (gestureRecognizer.state) {  
  22.         case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded  
  23.             NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");  
  24.             break;  
  25.         }  
  26.         case UIGestureRecognizerStateBegan:{ //   
  27.             NSLog(@"======UIGestureRecognizerStateBegan");  
  28.             break;  
  29.         }  
  30.         case UIGestureRecognizerStateChanged:{ //   
  31.             NSLog(@"======UIGestureRecognizerStateChanged");  
  32.             gestureRecognizer.view.transform = CGAffineTransformRotate(gestureRecognizer.view.transform, gestureRecognizer.rotation);  
  33.             gestureRecognizer.rotation = 0; // 重置 這個相當重要!!!   
  34.             break;  
  35.         }  
  36.         case UIGestureRecognizerStateCancelled:{ //   
  37.             NSLog(@"======UIGestureRecognizerStateCancelled");  
  38.             break;  
  39.         }  
  40.         case UIGestureRecognizerStateFailed:{ //   
  41.             NSLog(@"======UIGestureRecognizerStateFailed");  
  42.             break;  
  43.         }  
  44.         case UIGestureRecognizerStatePossible:{ //   
  45.             NSLog(@"======UIGestureRecognizerStatePossible");  
  46.             break;  
  47.         }  
  48.         default:{  
  49.             NSLog(@"======Unknow gestureRecognizer");  
  50.             break;  
  51.         }  
  52.     }    
  53. }  

UISwipeGestureRecognizer

[cpp]  view plain  copy

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view from its nib.  
  5.     // right  
  6.     UISwipeGestureRecognizer *swipeGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  7.     if (![swipeGestureRight respondsToSelector:@selector(locationInView:)]) {  
  8.         [swipeGestureRight release];  
  9.         swipeGestureRight = nil;  
  10.     }else {  
  11.         swipeGestureRight.delegate = self;  
  12.         swipeGestureRight.numberOfTouchesRequired = 1;// 手指個數 The default value is 1.  
  13.         swipeGestureRight.direction = UISwipeGestureRecognizerDirectionRight;// 同一個手勢隻能指定一個方向,不能同時指定多個方向,要指定多個方向 必須用多個手勢  
  14.         [self.view addGestureRecognizer:swipeGestureRight];  
  15.     }  
  16.     // left  
  17.     UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  18.     if (![swipeGestureLeft respondsToSelector:@selector(locationInView:)]) {  
  19.         [swipeGestureLeft release];  
  20.         swipeGestureLeft = nil;  
  21.     }else {  
  22.         swipeGestureLeft.delegate = self;  
  23.         swipeGestureLeft.numberOfTouchesRequired = 1;// 手指個數 The default value is 1.  
  24.         swipeGestureLeft.direction = UISwipeGestureRecognizerDirectionLeft;// 同一個手勢隻能指定一個方向,不能同時指定多個方向,要指定多個方向 必須用多個手勢  
  25.         [self.view addGestureRecognizer:swipeGestureLeft];  
  26.     }  
  27.     // Up  
  28.     UISwipeGestureRecognizer *swipeGestureUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  29.     if (![swipeGestureUp respondsToSelector:@selector(locationInView:)]) {  
  30.         [swipeGestureUp release];  
  31.         swipeGestureUp = nil;  
  32.     }else {  
  33.         swipeGestureUp.delegate = self;  
  34.         swipeGestureUp.numberOfTouchesRequired = 1;// 手指個數 The default value is 1.  
  35.         swipeGestureUp.direction = UISwipeGestureRecognizerDirectionUp;// 同一個手勢隻能指定一個方向,不能同時指定多個方向,要指定多個方向 必須用多個手勢  
  36.         [self.view addGestureRecognizer:swipeGestureUp];  
  37.     }  
  38.     // Down  
  39.     UISwipeGestureRecognizer *swipeGestureDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  40.     if (![swipeGestureDown respondsToSelector:@selector(locationInView:)]) {  
  41.         [swipeGestureDown release];  
  42.         swipeGestureDown = nil;  
  43.     }else {  
  44.         swipeGestureDown.delegate = self;  
  45.         swipeGestureDown.numberOfTouchesRequired = 1;// 手指個數 The default value is 1.  
  46.         swipeGestureDown.direction = UISwipeGestureRecognizerDirectionDown;// 同一個手勢隻能指定一個方向,不能同時指定多個方向,要指定多個方向 必須用多個手勢  
  47.         [self.view addGestureRecognizer:swipeGestureDown];  
  48.     }  
  49. }  
  50. - (void)handleGesture:(UISwipeGestureRecognizer *)gestureRecognizer  
  51. {  
  52.     UIView *view = [gestureRecognizer view]; // 這個view是手勢所屬的view,也就是增加手勢的那個view  
  53.     UISwipeGestureRecognizerDirection direction = gestureRecognizer.direction;  
  54.     switch (direction) {  
  55.         case UISwipeGestureRecognizerDirectionRight:  
  56.         {  
  57.             NSLog(@"direction==UISwipeGestureRecognizerDirectionRight");  
  58.             break;  
  59.         }  
  60.         case UISwipeGestureRecognizerDirectionLeft:  
  61.         {  
  62.             NSLog(@"direction==UISwipeGestureRecognizerDirectionLeft");  
  63.             break;  
  64.         }  
  65.         case UISwipeGestureRecognizerDirectionUp:  
  66.         {  
  67.             NSLog(@"direction==UISwipeGestureRecognizerDirectionUp");  
  68.             break;  
  69.         }  
  70.         case UISwipeGestureRecognizerDirectionDown:  
  71.         {  
  72.             NSLog(@"direction==UISwipeGestureRecognizerDirectionDown");  
  73.             break;  
  74.         }  
  75.         default:  
  76.             break;  
  77.     }  
  78.     switch (gestureRecognizer.state) {  
  79.         case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded  
  80.             NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");  
  81.             break;  
  82.         }  
  83.         default:{  
  84.             NSLog(@"======Unknow gestureRecognizer");  
  85.             break;  
  86.         }  
  87.     }    
  88. }  

UIPanGestureRecognizer

[cpp]  view plain  copy

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view from its nib.  
  5.     UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];  
  6.     view.backgroundColor = [UIColor blueColor];  
  7.     [self.view addSubview:view];  
  8.     UIPanGestureRecognizer *panPressGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  9.     if (![panPressGesture respondsToSelector:@selector(locationInView:)]) {  
  10.         [panPressGesture release];  
  11.         panPressGesture = nil;  
  12.     }else {  
  13.         panPressGesture.delegate = self;  
  14.         panPressGesture.maximumNumberOfTouches = NSUIntegerMax;// The default value is NSUIntegerMax.   
  15.         panPressGesture.minimumNumberOfTouches = 1;// The default value is 1.  
  16.         [view addGestureRecognizer:panPressGesture];  
  17.     }  
  18. }  
  19. // 拖拽手勢  
  20. - (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer  
  21. {  
  22.     UIView *view = [gestureRecognizer view]; // 這個view是手勢所屬的view,也就是增加手勢的那個view  
  23.     switch (gestureRecognizer.state) {  
  24.         case UIGestureRecognizerStateBegan:{   
  25.             NSLog(@"======UIGestureRecognizerStateBegan");  
  26.             break;  
  27.         }  
  28.         case UIGestureRecognizerStateChanged:{   
  29.             NSLog(@"======UIGestureRecognizerStateChanged");  
  30.             CGPoint translation = [gestureRecognizer translationInView:self.view];  
  31.             view.center = CGPointMake(gestureRecognizer.view.center.x + translation.x, gestureRecognizer.view.center.y + translation.y);  
  32.             [gestureRecognizer setTranslation:CGPointMake(0, 0) inView:self.view];//  注意一旦你完成上述的移動,将translation重置為0十分重要。否則translation每次都會疊加,很快你的view就會移除螢幕!  
  33.             break;  
  34.         }  
  35.         case UIGestureRecognizerStateCancelled:{   
  36.             NSLog(@"======UIGestureRecognizerStateCancelled");  
  37.             break;  
  38.         }  
  39.         case UIGestureRecognizerStateFailed:{   
  40.             NSLog(@"======UIGestureRecognizerStateFailed");  
  41.             break;  
  42.         }  
  43.         case UIGestureRecognizerStatePossible:{   
  44.             NSLog(@"======UIGestureRecognizerStatePossible");  
  45.             break;  
  46.         }  
  47.         case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded  
  48.             NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");  
  49.             CGPoint velocity = [gestureRecognizer velocityInView:self.view];// 分别得出x,y軸方向的速度向量長度(velocity代表按照目前速度,每秒可移動的像素個數,分xy軸兩個方向)  
  50.             CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));// 根據直角三角形的算法算出綜合速度向量長度  
  51.             // 如果長度小于200,則減少基本速度,否則增加它。  
  52.             CGFloat slideMult = magnitude / 200;  
  53.             NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);  
  54.             float slideFactor = 0.1 * slideMult; // Increase for more of a slide  
  55.             // 基于速度和滑動因子計算終點  
  56.             CGPoint finalPoint = CGPointMake(view.center.x + (velocity.x * slideFactor),  
  57.                                              view.center.y + (velocity.y * slideFactor));  
  58.             // 确定終點在視圖邊界内  
  59.             finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);  
  60.             finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);  
  61.             [UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{  
  62.                 view.center = finalPoint;    
  63.             } completion:nil];  
  64.             break;  
  65.         }  
  66.         default:{  
  67.             NSLog(@"======Unknow gestureRecognizer");  
  68.             break;  
  69.         }  
  70.     }    
  71. }  

UILongPressGestureRecognizer

[cpp]  view plain  copy

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view from its nib.  
  5.     UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];  
  6.     if (![longPressGesture respondsToSelector:@selector(locationInView:)]) {  
  7.         [longPressGesture release];  
  8.         longPressGesture = nil;  
  9.     }else {  
  10.         longPressGesture.delegate = self;  
  11.         longPressGesture.numberOfTapsRequired = 0;      // The default number of taps is 0.  
  12.         longPressGesture.minimumPressDuration = 0.1f;    // The default duration is is 0.5 seconds.  
  13.         longPressGesture.numberOfTouchesRequired = 1;   // The default number of fingers is 1.  
  14.         longPressGesture.allowableMovement = 10;        // The default distance is 10 pixels.  
  15.         [self.view addGestureRecognizer:longPressGesture];  
  16.     }  
  17. }  
  18. - (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer  
  19. {  
  20.     UIView *view = [gestureRecognizer view]; // 這個view是手勢所屬的view,也就是增加手勢的那個view  
  21.     switch (gestureRecognizer.state) {  
  22.         case UIGestureRecognizerStateEnded:{ // UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded  
  23.             NSLog(@"======UIGestureRecognizerStateEnded || UIGestureRecognizerStateRecognized");  
  24.             break;  
  25.         }  
  26.         case UIGestureRecognizerStateBegan:{ //   
  27.             NSLog(@"======UIGestureRecognizerStateBegan");  
  28.             break;  
  29.         }  
  30.         case UIGestureRecognizerStateChanged:{ //   
  31.             NSLog(@"======UIGestureRecognizerStateChanged");  
  32.             break;  
  33.         }  
  34.         case UIGestureRecognizerStateCancelled:{ //   
  35.             NSLog(@"======UIGestureRecognizerStateCancelled");  
  36.             break;  
  37.         }  
  38.         case UIGestureRecognizerStateFailed:{ //   
  39.             NSLog(@"======UIGestureRecognizerStateFailed");  
  40.             break;  
  41.         }  
  42.         case UIGestureRecognizerStatePossible:{ //   
  43.             NSLog(@"======UIGestureRecognizerStatePossible");  
  44.             break;  
  45.         }  
  46.         default:{  
  47.             NSLog(@"======Unknow gestureRecognizer");  
  48.             break;  
  49.         }  
  50.     }    
  51. }  
  52. // 詢問一個手勢接收者是否應該開始解釋執行一個觸摸接收事件  
  53. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{  
  54.     CGPoint currentPoint = [gestureRecognizer locationInView:self.view];  
  55.     if (CGRectContainsPoint(CGRectMake(0, 0, 100, 100), currentPoint) ) {  
  56.         return YES;  
  57.     }  
  58.     return NO;  
  59. }  
  60. // 詢問delegate,兩個手勢是否同時接收消息,傳回YES同僚接收。傳回NO,不同是接收(如果另外一個手勢傳回YES,則并不能保證不同時接收消息)the default implementation returns NO。  
  61. // 這個函數一般在一個手勢接收者要阻止另外一個手勢接收自己的消息的時候調用  
  62. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{  
  63.     return NO;  
  64. }  
  65. // 詢問delegate是否允許手勢接收者接收一個touch對象  
  66. // 傳回YES,則允許對這個touch對象稽核,NO,則不允許。  
  67. // 這個方法在touchesBegan:withEvent:之前調用,為一個新的touch對象進行調用  
  68. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{  
  69.     return YES;  
  70. }