IOS中我们可以通过UITouch进行触摸事件监听,但是UITouch实现捏合、旋转、长按等手势事件监听非常麻烦。IOS中提供 UIGestureRecognizer 的子类帮我们简洁等实现捏合、旋转等特殊手势监听。并且一个视图可添加多个不同等手势监听器。

开启userInteractionEnabled

IOS 中UIView 默认是不可响应事件的,我们需要开启 userInteractionEnabled 方可进行事件响应。下面代码中我们创建了一个图片视图,并且开始事件响应。UIView 通过 addGestureRecognizer 进行添加手势监听器和 removeGestureRecognizer删除手势监听器

// 创建图片视图
- (void) creareImg {UIImage* image = [UIImage imageNamed:@"zz.jpeg"];_imageView = [[UIImageView alloc] initWithImage:image];UIScreen* screen = [UIScreen mainScreen];const int width = 200;const int height = 100;const float x = screen.bounds.size.width / 2 - width / 2;const float y = screen.bounds.size.height / 2 - height;_imageView.frame = CGRectMake(x, y, width, height);_imageView.userInteractionEnabled = YES;[self.view addSubview:_imageView];
}

了解UIGestrueRecognizer

在开始使用自定义手势之前我们先了解一下 UIGestrueRecognizer 的,因为自定义都是基于 UIGestrueRecognizer 继承实现的。 UIGestrueRecognizer 是一个手势监听器,它可以设置多个手指同时触发触发事件等行为。它具有代理协议 UIGestureRecognizerDelegate 下面我来看一下它主要的属性和API、代理方法。

属性
名称 类型 说明 默认值
state UIGestureRecognizerState 当前手势状态,可分为手势开始,手势改变,手势结束等等
enabled BOOL 是否启用 YES
view UIView 手势监听的视图
requiresExclusiveTouchType BOOL 是否忽略其他手势类型,设置为YES将只响应一种手势类型 NO
numberOfTouches NSUInteger 多少根手指触发手势 1
API
  • - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action 初始化并添加事件监听函数
  • - (void)addTarget:(id)target action:(SEL)action 添加事件监听函数
  • - (void)removeTarget:(nullable id)target action:(nullable SEL)action 删除事件监听函数
  • - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer 添加其他手势冲突失效器,当触发当前手势时,指定的手势将失效。
  • - (CGPoint)locationInView:(nullable UIView*)view 获取相对于指定视图的坐标位置
  • - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view 获取指定手指相对指定视图的坐标位置
代理协议
  • - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 手势准备开启时候触发,返回NO则取消手势。

  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 当手势与其他手势同时发生识别时候触发,返回YES运行两个手势同时进行,返回NO则阻止同时识别。

  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 是否给事件接收手指。在手势开始触发事件触发前触发,返回NO可以阻止事件获取触摸的手指。

  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press 是否给按下事件接收手指,在按下手势事件触发前触发。返回NO可阻止事件获取触摸的手指。

我们了解清除GestureRecognizer 类,下面我们来了解其子类手势的使用。

UITapGestureRecognizer 点击手势

点击手势,可设置手指数量、点击次数触发的手势

// 创建点击手势
- (void) createTapGes {_imageView.userInteractionEnabled = YES; // 开启响应事件属性UITapGestureRecognizer* tapOneGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(big)]; // 创建手势tapOneGes.numberOfTapsRequired = 1; // 触发事件的点击次数tapOneGes.numberOfTouchesRequired = 1; // 触发事件的手指数量[_imageView addGestureRecognizer:tapOneGes]; // 添加手势监听器
}
// 点击触发事件
- (void) big {UIScreen* screen = [UIScreen mainScreen];[UIView beginAnimations:nil context:nil]; // 开始布局动画_imageView.frame = CGRectMake(0, 0, screen.bounds.size.width, screen.bounds.size.height);[UIView commitAnimations]; // 结束布局动画
}

UIPinchGestureRecognizer 捏合手势

捏合手势,表示双指捏合缩放的手势触发。常用于对图片查看缩放事件监听

// 捏合手势
- (void) createPinchGes {UIPinchGestureRecognizer* pinch = [[UIPinchGestureRecognizer alloc] init]; // 创建手势[pinch addTarget:self action:@selector(scale:)]; // 添加事件函数pinch.delegate = self; // 设置代理[_imageView addGestureRecognizer:pinch]; // 视图添加手势监听器
}- (void) scale: (UIPinchGestureRecognizer*) pinch {UIView* IView = pinch.view; // 获取监听的视图CGAffineTransform transiform = CGAffineTransformScale(IView.transform, pinch.scale, pinch.scale); // 计算缩放后的矩阵if (transiform.a < 0.4) { // 缩放小于0.4阻止transiform.a = 0.4;transiform.d = 0.4;}IView.transform = transiform; // 重新设置矩阵pinch.scale = 1; // 重置缩放矩阵,否则手势会一直累加
}// 添加允许多个手势触发代理函数
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {return  YES;
}

上面代码中我们通过获取捏合手势的scale 属性获取用户捏合缩放的大小。并且使用内置api CGAffineTransformScale 重新计算了视图的2D矩阵(矩阵表示图像变形,可以了解一下图形学),注意!最后一步中必须重置手势的scale 否则会一直累加导致计算矩阵错误,如果不想重置的话那就需要修改 CGAffineTransformScale的第一个参数为基础矩阵参数。

UIRotationGestureRecognizer 旋转手势

旋转手势,可获取用户手指旋转的角度。

// 旋转手势
- (void) createRotateGes {UIRotationGestureRecognizer* rotate = [[UIRotationGestureRecognizer alloc] init];[rotate addTarget:self action:@selector(rotate:)];rotate.delegate = self;[_imageView addGestureRecognizer:rotate];
}
// 旋转触发事件
- (void) rotate: (UIRotationGestureRecognizer*) rotate {UIView* IView = rotate.view;IView.transform =  CGAffineTransformRotate(IView.transform, rotate.rotation); // 重新计算视图矩阵rotate.rotation = 0;
}

UIPanGestureRecognizer 平移手势

平移动手势,比较简单就是手指移动时候触发,但是提供平移的位置和平移的速度

// 平移手势
- (void) createPanGes {UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];pan.delegate = self;[_imageView addGestureRecognizer:pan];
}
- (void) pan: (UIPanGestureRecognizer*)pan {CGPoint speed = [pan velocityInView:_imageView]; // 获取移动速度NSLog(@"x速度= %f, y速度= %f", speed.x, speed.y);CGPoint translation = [pan translationInView:_imageView]; // 获取移动矩阵CGAffineTransform transform = CGAffineTransformTranslate(_imageView.transform, translation.x, translation.y);_imageView.transform = transform;
}

UILongPressGestureRecognizer 长按手势

长按对应视图触发手势,可设置手指数量和手指长按时间

// 长按手势
- (void) createLongPassGes {UILongPressGestureRecognizer* longPass = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pass:)];longPass.minimumPressDuration = 1; // 设置长按触发时间,默认0.5[_imageView addGestureRecognizer: longPass];
}- (void)pass: (UILongPressGestureRecognizer*) longPass {if (longPass.state == UIGestureRecognizerStateBegan) {NSLog(@"开始长按");} else if (longPass.state == UIGestureRecognizerStateEnded) {NSLog(@"结束长按");} else if (longPass.state == UIGestureRecognizerStateChanged) {NSLog(@"长按发生改变");}
}

UISwipeGestureRecognizer 轻滑手势

轻滑手势,类似我们的平移手势。但是轻滑不同的是在用户快速滑动时候速度,并且只提供滑动方向。

// 创建轻滑手势
- (void) createSwipe {UISwipeGestureRecognizer* swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiper:)];swipe.direction = UISwipeGestureRecognizerDirectionDown;[_imageView addGestureRecognizer: swipe];swipe.delegate = self;
}- (void) swiper: (UISwipeGestureRecognizer*)swiper {NSLog(@"发生向下滑动");
}

IOS 定义手势监听器详解,利用 UIGestureRecognizer 进行捏合、旋转、平移、点击、长按手势事件响应相关推荐

  1. pygame的基础知识详解(主窗口创建、图像绘制、时钟对象和事件响应等知识点),请惠存

    各位好,很久没更新博客了,最近较为深入研究pygame库,有些心得体会,想分享给各位,准备做成一个系列知识.欢迎各位查阅. 这篇作为一个基础知识的宣贯,想和各位深入分享一下pygame的基础知识,深入 ...

  2. iOS里面MVC模式详解

    iOS里面MVC模式详解 MVC是IOS里面也是很多程序设计里面的一种设计模式,M是model,V是view,C是controller.MVC模式在ios开发里面可谓是用得淋漓尽致. 以下是对斯坦福大 ...

  3. iOS开发证件要点详解

    iOS开发证书要点详解 引言 关于开发证书配置(Certificates&Identifiers&Provisioning Profiles),相信做iOS开发的同学没少被折腾.对于一 ...

  4. iOS中ImageIO框架详解与应用分析

    2019独角兽企业重金招聘Python工程师标准>>> iOS中ImageIO框架详解与应用分析 一.引言 ImageIO框架提供了读取与写入图片数据的基本方法,使用它可以直接获取到 ...

  5. iOS动画-CAAnimation使用详解

    理解了隐式动画后,显式动画就更加通俗易懂了.区别于隐式动画的特点,显式动画就是需要我们明确指定类型.时间等参数来实现效果的动画.除此之外,我们也可以创建非线性动画,比如沿着任意一条曲线运动等: 我们平 ...

  6. [置顶] iOS中 支付宝钱包详解/第三方支付

    [置顶] iOS中 支付宝钱包详解/第三方支付 韩俊强的博客 每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 一.在app中成功完成支付宝支付的过程 1.申请支付 ...

  7. Listener(监听器)详解

    Listener(监听器)详解 作用:监听某个事件的发生,状态的改变 内部机制:接口回调 监听器用于监听Web应用中某些对象的创建.销毁.增加,修改,删除等动作的发生,然后作出相应的响应处理.当监听范 ...

  8. Flutter开发之iOS后台定位开发详解

    Flutter开发之iOS后台定位开发详解 需求目的 开发一个功能持续获取用户的位置发送给后端,PC端会根据后端传来的移动端发送的位置信息,来绘制使用者的运动轨迹. 实现需求 是否实现 后台定位 ✅ ...

  9. Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解

    Spring MVC 学习总结(二)--控制器定义与@RequestMapping详解 目录 一.控制器定义 1.1.实现接口Controller定义控制器 1.2.使用注解@Controller定义 ...

最新文章

  1. python batch normalization_python – Keras BatchNormalization,样本明智规范化究竟是什么?...
  2. 为什么总线要用一根来表示一bit
  3. Linux的mount命令简介
  4. CSS选择器、盒子模型及布局
  5. ASP.NET Core 实现基于 ApiKey 的认证
  6. P3195 [HNOI2008]玩具装箱TOY
  7. Python精通-Python学习路线详细介绍
  8. redis-对象的存储-JSON
  9. 小黑小波比.Ubuntu14.04安装ffmpeg以及使用ffmpeg
  10. 【转】sql语句优化工具LECCO SQL Expert
  11. phpstudy php56 zend,phpstudy集成环境
  12. 如何通过域名查询IP地址
  13. gazebo教程(八)场景建模
  14. 阿星 centos7卸载mysql并且通过yum安装mysql
  15. 小米怎么快速回到顶部_灵巧精干的出游神器 小米对讲机Lite上手体验
  16. 计算机共享文件误删怎么恢复,在电脑上不小心把共享里的EXCEL表格数据给删除了,该怎么恢复这个文件的数据啊?,excel表格里误删数据恢复...
  17. 抽象类和接口(Java程序设计)
  18. 三国杀 官方 游戏规则
  19. 微信支付二维码上添加logo
  20. react-native 调用第三方 SDK

热门文章

  1. iview table增加一行减少一行_PQ入门函数:Table.ReplaceValue
  2. oracle查询慢怎么优化,Oracle查询优化-怎样建立索引优化下面的查询语句啊
  3. linux perl的while循环中ctrl+c失效,perl循环控制
  4. 使用 保存文件_使用SaveFileDialog调用保存文件对话框
  5. C/C++如何快速区分指针数组|数组指针|函数指针|指针函数
  6. win2008验证服务器错误,win2008dcdiag检测出的错误,求解决方法
  7. java oo 封装_Java从小白到入门,Day6。JAVAOO-封装
  8. flume linux 命令,Linux环境Flume安装配置及使用
  9. pythonwebui自动化_python+selenium实现web端UI自动化测试
  10. 机器人炒饭小块头一一_小块头机器人炒饭:全智能流程,炒饭芬芳独具