IOS 定义手势监听器详解,利用 UIGestureRecognizer 进行捏合、旋转、平移、点击、长按手势事件响应
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 进行捏合、旋转、平移、点击、长按手势事件响应相关推荐
- pygame的基础知识详解(主窗口创建、图像绘制、时钟对象和事件响应等知识点),请惠存
各位好,很久没更新博客了,最近较为深入研究pygame库,有些心得体会,想分享给各位,准备做成一个系列知识.欢迎各位查阅. 这篇作为一个基础知识的宣贯,想和各位深入分享一下pygame的基础知识,深入 ...
- iOS里面MVC模式详解
iOS里面MVC模式详解 MVC是IOS里面也是很多程序设计里面的一种设计模式,M是model,V是view,C是controller.MVC模式在ios开发里面可谓是用得淋漓尽致. 以下是对斯坦福大 ...
- iOS开发证件要点详解
iOS开发证书要点详解 引言 关于开发证书配置(Certificates&Identifiers&Provisioning Profiles),相信做iOS开发的同学没少被折腾.对于一 ...
- iOS中ImageIO框架详解与应用分析
2019独角兽企业重金招聘Python工程师标准>>> iOS中ImageIO框架详解与应用分析 一.引言 ImageIO框架提供了读取与写入图片数据的基本方法,使用它可以直接获取到 ...
- iOS动画-CAAnimation使用详解
理解了隐式动画后,显式动画就更加通俗易懂了.区别于隐式动画的特点,显式动画就是需要我们明确指定类型.时间等参数来实现效果的动画.除此之外,我们也可以创建非线性动画,比如沿着任意一条曲线运动等: 我们平 ...
- [置顶] iOS中 支付宝钱包详解/第三方支付
[置顶] iOS中 支付宝钱包详解/第三方支付 韩俊强的博客 每日更新关注:http://weibo.com/hanjunqiang 新浪微博! 一.在app中成功完成支付宝支付的过程 1.申请支付 ...
- Listener(监听器)详解
Listener(监听器)详解 作用:监听某个事件的发生,状态的改变 内部机制:接口回调 监听器用于监听Web应用中某些对象的创建.销毁.增加,修改,删除等动作的发生,然后作出相应的响应处理.当监听范 ...
- Flutter开发之iOS后台定位开发详解
Flutter开发之iOS后台定位开发详解 需求目的 开发一个功能持续获取用户的位置发送给后端,PC端会根据后端传来的移动端发送的位置信息,来绘制使用者的运动轨迹. 实现需求 是否实现 后台定位 ✅ ...
- Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解
Spring MVC 学习总结(二)--控制器定义与@RequestMapping详解 目录 一.控制器定义 1.1.实现接口Controller定义控制器 1.2.使用注解@Controller定义 ...
最新文章
- python batch normalization_python – Keras BatchNormalization,样本明智规范化究竟是什么?...
- 为什么总线要用一根来表示一bit
- Linux的mount命令简介
- CSS选择器、盒子模型及布局
- ASP.NET Core 实现基于 ApiKey 的认证
- P3195 [HNOI2008]玩具装箱TOY
- Python精通-Python学习路线详细介绍
- redis-对象的存储-JSON
- 小黑小波比.Ubuntu14.04安装ffmpeg以及使用ffmpeg
- 【转】sql语句优化工具LECCO SQL Expert
- phpstudy php56 zend,phpstudy集成环境
- 如何通过域名查询IP地址
- gazebo教程(八)场景建模
- 阿星 centos7卸载mysql并且通过yum安装mysql
- 小米怎么快速回到顶部_灵巧精干的出游神器 小米对讲机Lite上手体验
- 计算机共享文件误删怎么恢复,在电脑上不小心把共享里的EXCEL表格数据给删除了,该怎么恢复这个文件的数据啊?,excel表格里误删数据恢复...
- 抽象类和接口(Java程序设计)
- 三国杀 官方 游戏规则
- 微信支付二维码上添加logo
- react-native 调用第三方 SDK
热门文章
- iview table增加一行减少一行_PQ入门函数:Table.ReplaceValue
- oracle查询慢怎么优化,Oracle查询优化-怎样建立索引优化下面的查询语句啊
- linux perl的while循环中ctrl+c失效,perl循环控制
- 使用 保存文件_使用SaveFileDialog调用保存文件对话框
- C/C++如何快速区分指针数组|数组指针|函数指针|指针函数
- win2008验证服务器错误,win2008dcdiag检测出的错误,求解决方法
- java oo 封装_Java从小白到入门,Day6。JAVAOO-封装
- flume linux 命令,Linux环境Flume安装配置及使用
- pythonwebui自动化_python+selenium实现web端UI自动化测试
- 机器人炒饭小块头一一_小块头机器人炒饭:全智能流程,炒饭芬芳独具