触摸事件与手势识别

UIViewUIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件。

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. 1. 一根或者多根手指开始触摸屏幕  
  2. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
  3. 2.一根或者多根手指在屏幕上移动(随着手指的移动,会持续调用该方法)  
  4. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event  
  5. 3.一根或者多根手指离开屏幕  
  6. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
  7. 4.触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程  
  8. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event  
  9. 注意:所有UIKit控件均继承自UIView  

常用属性:

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. 1.UITouch *touch = [touches anyObject];//1. 从NSSet中取出UITouch对象  
  2. 2.CGPoint location = [touch locationInView:self.view];//// 2. 手指触摸的位置  
  3. 3.[touch previousLocationInView:]方法对位置进行修正  
  4. 4.touches.count来判断是多点还是单点触摸  
  5. 5. [self.view setMultipleTouchEnabled:YES]设置为yes 支持多点触摸  
  6. 6.CGPoint greenPoint = [selfconvertPoint:point toView:self.greenView];//将point有点击的试图转到greenView上,返回此点在greenView上到坐标  
  7. 7.[self.greenViewpointInside:greenPoint withEvent:event]判断greenPoint是否在greenView上  
  8. 8.[touch view] 获取但前触摸到试图  

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #pragma mark 触摸移动 -在一次触摸事件中,可能会被调用多次  
  2. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event  
  3. {  
  4.     // 1. 从NSSet中取出UITouch对象  
  5.     UITouch *touch = [touchesanyObject];  
  6.     // 2. 知道手指触摸的位置  
  7.     CGPoint location = [touchlocationInView:self.view];  
  8.     // 2.1 可以利用[touch previousLocationInView:]方法对位置进行修正  
  9.     CGPoint pLocation = [touchpreviousLocationInView:self.view];  
  10.     CGPoint deltaP =CGPointMake(location.x - pLocation.x, location.y - pLocation.y);  
  11.     CGPoint newCenter =CGPointMake(self.redView.center.x + deltaP.x, self.redView.center.y + deltaP.y);  
  12.       
  13.     // 3. 设置红色视图的位置  
  14.     [self.redViewsetCenter:newCenter];  
  15. }  



 

多点触摸:

iOS中,视图默认不支持多点触摸,通常在使用UITouch开发时,为了避免不必要的麻烦,也最好不要支持多点

需要支持多点必须把 [self.viewsetMultipleTouchEnabled:YES]设置为yes

 

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event  
  2. {  
  3.    //可以通过touches.count来判断是多点还是单点触摸  
  4.     // 遍历touches集合来添加图像  
  5.     NSInteger i =0;  
  6.     for (UITouch *touchin touches) {  
  7.         UIImageView *imageView = [[UIImageViewalloc]initWithImage:self.images[i]];  
  8.         CGPoint location = [touchlocationInView:self.view];//手指触摸的位置  
  9.         [imageView setCenter:location];  
  10.         [self.viewaddSubview:imageView];  
  11.         [UIViewanimateWithDuration:2.0fanimations:^{  
  12.             [imageView setAlpha:0.5f];  
  13.         } completion:^(BOOL finished) {  
  14.             [imageView removeFromSuperview];  
  15.         }];  
  16.           
  17.         i++;  
  18.     }  
  19. }  



摇晃事件:

摇晃的试图必须重写此方法,并返回yes

 

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
 
    1. - (BOOL)canBecomeFirstResponder  
    2. {  
    3.     returnYES;  
    4. }  
    5. #pragma mark - 监听运动事件  
    6. - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event  
    7. {  
    8.     if (UIEventSubtypeMotionShake == motion) {  
    9.         NSLog(@"摇晃啦");  
    10.         // 摇晃的后续处理  
    11.         //  
    12.         // 1. 记录用户当前位置(经纬度)  
    13.         // 2. 去服务器上查询当前摇晃手机的用户记录  
    14.         // 3. 根据用户所在经纬度,取出前N名距离用户最近的用户记录  
    15.         // 4. 将用户记录发送到用户手机  
    16.         // 5. 手机接收到数据后,self.tableView reloadData  
    17.     }  
    18. }  
    19. [objc] view plaincopy在CODE上查看代码片派生到我的代码片
       
      1. // 1. 点按手势  
      2.     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];  
      3.     // 点按次数,例如双击2  
      4.     // 注意:在iOS中最好少用双击,如果一定要用,就一定要有一个图形化的界面告知用户可以双击  
      5.     [tap setNumberOfTapsRequired:2];  
      6.     // 用几根手指点按  
      7.     [tap setNumberOfTouchesRequired:1];  
      8.     [imageView addGestureRecognizer:tap];  
      9.       
      10.     // 2. 长按手势 Long Press  
      11.     UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longTap:)];  
      12.     [imageView addGestureRecognizer:longTap];  
      13.       
      14.     // 3. 拖动手势 Pan  
      15.     UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];  
      16.     [imageView addGestureRecognizer:pan];  
      17.       
      18.     // 4. 旋转手势 Rotation  
      19.     UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotation:)];  
      20.     [imageView addGestureRecognizer:rotation];  
      21.       
      22.     // 5. 缩放(捏合)手势 Pinch  
      23.     UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];  
      24.     [imageView addGestureRecognizer:pinch];  
      25.       
      26.     // 6. 轻扫手势 Swipe  
      27.     /* 
      28.      手指在屏幕上扫动,和拖动手势的区别在于,手指离开屏幕才会触发监听方法 
      29.       
      30.      1> 手指可以上、下、左、右四个方向轻轻扫动,如果没有指定方向,默认都是向右扫动 
      31.      2> 在设置轻扫手势时,通常需要将手势识别添加到父视图上监听 
      32.      3> 在监听方法中,注意不要使用recognizaer.view,因为手势监听的是父视图,而要处理的视图通常是其他的视图 
      33.       
      34.      如果要使用多个方向的轻扫手势,需要指定多个轻扫手势,通常只需指定左右两个方向即可。 
      35.       
      36.      因为iOS用户大多不习惯上下的轻扫动作 
      37.      */  
      38.     UISwipeGestureRecognizer *swipe1 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];  
      39.     [swipe1 setDirection:UISwipeGestureRecognizerDirectionUp];  
      40.     [self.view addGestureRecognizer:swipe1];  
      41.       
      42.     UISwipeGestureRecognizer *swipe2 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];  
      43.     [swipe2 setDirection:UISwipeGestureRecognizerDirectionDown];  
      44.     [self.view addGestureRecognizer:swipe2];  
      45.       
      46.     UISwipeGestureRecognizer *swipe3 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];  
      47.     [swipe3 setDirection:UISwipeGestureRecognizerDirectionLeft];  
      48.     [self.view addGestureRecognizer:swipe3];  
      49.       
      50.     UISwipeGestureRecognizer *swipe4 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];  
      51.     [swipe4 setDirection:UISwipeGestureRecognizerDirectionRight];  
      52.     [self.view addGestureRecognizer:swipe4];  

      [objc] view plaincopy在CODE上查看代码片派生到我的代码片
       
      1. #pragma mark - 手势监听方法  
      2. #pragma mark 轻扫手势  
      3. // 尽管轻扫手势也是连续手势,但是该手势是在手指离开屏幕才会被触发的  
      4. // 因此,在编写代码时,不需要处理手势的状态  
      5. - (void)swipe:(UISwipeGestureRecognizer *)recognizer  
      6. {  
      7.     // 让图片朝手指不同的方向飞出屏幕,然后再复位  
      8.     CGRect frame = kImageInitFrame;  
      9.     if (UISwipeGestureRecognizerDirectionUp == recognizer.direction) {  
      10.         frame.origin.y -= 400;  
      11.     } else if (UISwipeGestureRecognizerDirectionDown == recognizer.direction) {  
      12.         frame.origin.y += 400;  
      13.     } else if (UISwipeGestureRecognizerDirectionLeft == recognizer.direction) {  
      14.         frame.origin.x -= 300;  
      15.     } else {  
      16.         frame.origin.x += 300;  
      17.     }  
      18.       
      19.     [UIView animateWithDuration:1.0 animations:^{  
      20.         [self.imageView setFrame:frame];  
      21.     } completion:^(BOOL finished) {  
      22.         [UIView animateWithDuration:1.0f animations:^{  
      23.             [self.imageView setFrame:kImageInitFrame];  
      24.         }];  
      25.     }];  
      26. }  
      27.   
      28. #pragma mark 捏合手势  
      29. - (void)pinch:(UIPinchGestureRecognizer *)recognizer  
      30. {  
      31.     /** 
      32.      变化过程中,放大缩小 
      33.      结束后,恢复 
      34.      */  
      35.     if (UIGestureRecognizerStateChanged == recognizer.state) {  
      36.         [recognizer.view setTransform:CGAffineTransformMakeScale(recognizer.scale, recognizer.scale)];  
      37.           
      38.     } else if (UIGestureRecognizerStateEnded == recognizer.state) {  
      39.         [UIView animateWithDuration:0.5f animations:^{  
      40.             // 恢复初始位置,清除所有的形变效果  
      41.             [recognizer.view setTransform:CGAffineTransformIdentity];  
      42.         }];  
      43.     }  
      44.       
      45. }  
      46.   
      47. #pragma mark 旋转手势,至少两根手指  
      48. - (void)rotation:(UIRotationGestureRecognizer *)recognizer  
      49. {  
      50.     // recognizer中的rotation属性是基于图片的初始旋转弧度的  
      51.     /** 
      52.      变化过程中,旋转 
      53.      结束后,恢复 
      54.      */  
      55.     if (UIGestureRecognizerStateChanged == recognizer.state) {  
      56.         [recognizer.view setTransform:CGAffineTransformMakeRotation(recognizer.rotation)];  
      57.         /**  
      58.          累加的形变 
      59.          */  
      60. //        [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation)];  
      61. //        // 把手势识别的rotation设置为0,在下一次触发时,以当前的旋转角度为基准继续旋转  
      62. //        recognizer.rotation = 0;  
      63.     } else if (UIGestureRecognizerStateEnded == recognizer.state) {  
      64.         [UIView animateWithDuration:0.5f animations:^{  
      65.             // 恢复初始位置,清除所有的形变效果  
      66.             [recognizer.view setTransform:CGAffineTransformIdentity];  
      67.         }];  
      68.     }  
      69. }  
      70.   
      71. #pragma mark 拖动手势  
      72. - (void)pan:(UIPanGestureRecognizer *)recognizer  
      73. {  
      74.     NSLog(@"拖动");  
      75.       
      76.     /* 
      77.      拖动手势结束后,以动画的方式回到初始位置 
      78.      */  
      79.     // 在手势状态处于“变化”时处理图片的移动  
      80.     // UIGestureRecognizerStateChanged类似于touchesMoved方法,会不断地被调用  
      81.     if (UIGestureRecognizerStateChanged == recognizer.state) {  
      82.   
      83.         // translationInView,判断在父视图中平移的位置,平移的偏移量始终以视图的初始位置为基础  
      84.         CGPoint deltaPoint = [recognizer translationInView:self.view];  
      85.   
      86.         // 用形变参数来改变图像的位置  
      87.         [recognizer.view setTransform:CGAffineTransformMakeTranslation(deltaPoint.x, deltaPoint.y)];  
      88.           
      89. //        CGRect targetRect = kImageInitFrame;  
      90. //        targetRect.origin.x += deltaPoint.x;  
      91. //        targetRect.origin.y += deltaPoint.y;  
      92. //          
      93. //        [recognizer.view setFrame:targetRect];  
      94.     } else if (UIGestureRecognizerStateEnded == recognizer.state) {  
      95.         [UIView animateWithDuration:0.5f animations:^{  
      96.             // 将图片复位  
      97. //            [recognizer.view setFrame:kImageInitFrame];  
      98.             [recognizer.view setTransform:CGAffineTransformIdentity];  
      99.         }];  
      100.     }  
      101. }  
      102.   
      103. #pragma mark 长按手势  
      104. - (void)longTap:(UILongPressGestureRecognizer *)recognizer  
      105. {  
      106.     NSLog(@"长按");  
      107.     /* 
      108.      旋转半圈的动画,动画完成后恢复 
      109.       
      110.      长按手势属于连续手势,是需要处理状态 
      111.       
      112.      因为长按通常只有一根手指,因此在Began状态下,长按手势就已经被识别了 
      113.       
      114.      针对长按的处理,最好放在UIGestureRecognizerStateBegan状态中实现 
      115.      */  
      116.     if (UIGestureRecognizerStateBegan == recognizer.state) {  
      117.         NSLog(@"长按");  
      118.           
      119.         [UIView animateWithDuration:1.0f animations:^{  
      120.             [recognizer.view setTransform:CGAffineTransformMakeRotation(M_PI)];  
      121.         } completion:^(BOOL finished) {  
      122.             // CGAffineTransformIdentity将视图的形变复原(平移、缩放、旋转)  
      123.             [recognizer.view setTransform:CGAffineTransformIdentity];  
      124.         }];  
      125.     } else if (UIGestureRecognizerStateEnded == recognizer.state) {  
      126. //        [UIView animateWithDuration:1.0f animations:^{  
      127. //            [recognizer.view setTransform:CGAffineTransformMakeRotation(M_PI)];  
      128. //        } completion:^(BOOL finished) {  
      129. //            // CGAffineTransformIdentity将视图的形变复原(平移、缩放、旋转)  
      130. //            [recognizer.view setTransform:CGAffineTransformIdentity];  
      131. //        }];  
      132.     }  
      133. }  
      134.   
      135. #pragma mark 点按手势  
      136. - (void)tap:(UITapGestureRecognizer *)recognizer  
      137. {  
      138.     NSLog(@"点我了");  
      139.     // 做一个动画效果  
      140.     // 向下移出屏幕,完成后再重新返回初始位置  
      141.     // recognizer.view 就是识别到手势的视图,也就是手势绑定到得视图  
      142.       
      143.     CGRect initFrame = recognizer.view.frame;  
      144.     CGRect targetFrame = recognizer.view.frame;  
      145.     targetFrame.origin.y += 360;  
      146.       
      147.     [UIView animateWithDuration:1.0f animations:^{  
      148.         // 自动反向重复动画  
      149.         [UIView setAnimationRepeatAutoreverses:YES];  
      150.         // 设置动画重复次数  
      151.         [UIView setAnimationRepeatCount:2];  
      152.           
      153.         [recognizer.view setFrame:targetFrame];  
      154.     } completion:^(BOOL finished) {  
      155.         [recognizer.view setFrame:initFrame];  
      156.     }];  
      157. }  
原文地址:https://www.cnblogs.com/seth-chen/p/4368047.html