iOS学习之事件处理的原理
2016-06-19 22:32
375 查看
在iOS学习23之事件处理中,小编详细的介绍了事件处理,在这里小编叙述一下它的相关原理
一根手指对应一个 UITouch 对象
UITouch 的作用
保存着根手指相关的信息,比如触摸的位置、时间、阶段
当手指移动时,系统会更新同一个 UITouch 对象,使之能够一直保持该手指在的触摸位置
当手指离开屏幕时,系统会销毁相应的 UITouch 对象
提示:iPhone 开发中,要避免使用双击事件!
触摸产生时所产生的视图
短时间内点按屏幕的次数,可以根据 tapCount 判断单击、双击或更多的点击
记录了触摸事件产生或变化时的时间,单位是秒
当前触摸事件所处的状态
方法一中返回的位置针对View的坐标系(以View的左上角为原点(0,0))
当方法一调用时传入的View参数为 nil 的话,返回的是触摸点在 UIWindow 的位置
实例代码:
默认不支持多个手指,要修改 Multiple Touch 属性,在 storyboard 中将这个属性打钩就可以
UIApplication 会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)
主窗口会在视图层次结构中找到一个最适合的视图来处理触摸事件,这也是整个事件处理过程的第一步
找到合适的视图控件后,就会调用视图控件的 touches 方法来做具体的事件处理
touchesBegan...
touchesMoved...
touchesEnded...
视图隐藏
透明
该方法的返回值就是事件处理的视图控件
当该方法在 UIWindow 类中重写,要使下图无论点哪里都是最底下白色的视图进行处理,就返回 self.subviews[0]。
判断触摸点是否在自己身上,底层实现方法:pointInside: withEvent:
从后往前遍历子控件,重复前面的两个步骤
1、UITouch对象
在触摸事件的处理方法中都会有一个存放着UITouch对象的集合,这个参数有什么用呢?(1)UITouch 对象的简介
当用户用一根手指触摸屏幕时,会创建一个与手指相关联的 UITouch 对象一根手指对应一个 UITouch 对象
UITouch 的作用
保存着根手指相关的信息,比如触摸的位置、时间、阶段
当手指移动时,系统会更新同一个 UITouch 对象,使之能够一直保持该手指在的触摸位置
当手指离开屏幕时,系统会销毁相应的 UITouch 对象
提示:iPhone 开发中,要避免使用双击事件!
(2)UITouch 的属性
触摸产生时所产生的窗口@property (nonatomic, readonly, retain) UIWindow *window;
触摸产生时所产生的视图
@property (nonatomic, readonly, retain) UIView *view;
短时间内点按屏幕的次数,可以根据 tapCount 判断单击、双击或更多的点击
@property (nonatomic, readonly) NSUInteger tapCount;
记录了触摸事件产生或变化时的时间,单位是秒
@property (nonatomic, readonly) NSTimeInterval timestamp;
当前触摸事件所处的状态
@property (nonatomic, readonly) UITouchPhase phase;
(3)UITouch 的方法
// 返回值表示触摸在View上的位置 - (CGPoint)locationInView:(UIView *)view; // 该方法记录了前一个触摸点的位置 - (CGPoint)previousLocationInView:(UIView *)view;
方法一中返回的位置针对View的坐标系(以View的左上角为原点(0,0))
当方法一调用时传入的View参数为 nil 的话,返回的是触摸点在 UIWindow 的位置
实例代码:
// 当手指在view上移动的时候 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"%s",__func__); // 获取UITouch对象 UITouch *touch = [touches anyObject]; // 获取当前点 CGPoint curP = [touch locationInView:self]; // 获取上一个点 CGPoint preP = [touch previousLocationInView:self]; // 获取x轴偏移量 CGFloat offsetX = curP.x - preP.x; // 获取y轴偏移量 CGFloat offsetY = curP.y - preP.y; // 修改view的位置(frame,center,transform) self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY); // self.transform = CGAffineTransformMakeTranslation(offsetX, 0); }
默认不支持多个手指,要修改 Multiple Touch 属性,在 storyboard 中将这个属性打钩就可以
2、原理
(1)事件的产生和传递
发生触摸事件后,系统会将该事件加入到一个由 UIApplication 管理的事件队列中UIApplication 会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)
主窗口会在视图层次结构中找到一个最适合的视图来处理触摸事件,这也是整个事件处理过程的第一步
找到合适的视图控件后,就会调用视图控件的 touches 方法来做具体的事件处理
touchesBegan...
touchesMoved...
touchesEnded...
(2)UIView不接收触摸事件的三种情况
用户交互关闭userInteractionEnabled = NO;
视图隐藏
hidden = YES;
透明
alpha = 0.0 ~ 0.1
(3)如何找到最适合的控件
判断自己是否能接收触摸事件,底层实现方法:hitTest: withEvent:// 作用:就是用来寻找最合适的view // 什么时候调用:当事件传递给控件的时候,就会调用控件的这个方法,去寻找最合适的view // point:当前的触摸点,point这个点的坐标系就是方法调用者 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // 调用系统的做法去寻找最合适的view,返回最合适的view UIView *fitView = [super hitTest:point withEvent:event]; return fitView; }
该方法的返回值就是事件处理的视图控件
当该方法在 UIWindow 类中重写,要使下图无论点哪里都是最底下白色的视图进行处理,就返回 self.subviews[0]。
判断触摸点是否在自己身上,底层实现方法:pointInside: withEvent:
// 作用:判断当前这个点在不在方法调用者(控件)上 // 在判断是否是最适合的控件的时候调用 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { return YES; }
从后往前遍历子控件,重复前面的两个步骤
相关文章推荐
- iOS新闻客户端开发教程8-加载更多和新闻详情
- iOS开发,javascript直接调用oc代码而非通过改变url回调方式
- iOS屏幕旋转学习笔记
- iOS开发之Socket
- Nagios 4.0.1安装
- 个人简历
- iOS是怎么被越狱的(UAF漏洞详解)
- iOS打包ipa步骤
- iOS百度地图 Demo
- iOS开发多线程篇 03 —线程安全
- IOS多线程开发
- [置顶] iOS应用程序执行流程
- iOS开发25个性能调优技巧
- iOS项目冗余资源扫描脚本
- ios 通过一个View生成一个图片
- ios sdk二维码生成器
- iOS使用半透明模糊效果方法整理
- IOS SDK图片二维码识别
- [置顶] iOS开发—单元测试
- iOS真机测试碰到错误linker command failed with exit code 1 (use -v to see invocation)