• 触摸事件与手势识别


    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. }  
  • 相关阅读:
    JMeter接口压测——ServerAgent监控服务端性能指标
    Appium系列文章(1)获取appPackage和appActivity
    【无私分享:ASP.NET CORE 项目实战】目录索引
    【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引
    【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现
    【无私分享:ASP.NET CORE 项目实战(第十三章)】Asp.net Core 使用MyCat分布式数据库,实现读写分离
    【无私分享:ASP.NET CORE 项目实战(第十二章)】添加对SqlServer、MySql、Oracle的支持
    【无私分享:ASP.NET CORE 项目实战(第十一章)】Asp.net Core 缓存 MemoryCache 和 Redis
    【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 (16)源码分享二:登录功能以及UI、数据库、仓储源码分享
    【无私分享:ASP.NET CORE 项目实战(第十章)】发布项目到 Linux 上运行 Core 项目
  • 原文地址:https://www.cnblogs.com/seth-chen/p/4368047.html
Copyright © 2020-2023  润新知