




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】ios开发
IOS学习可以先从基础开始,以后会介绍写内容吧这篇文章想跟大家分享的主旨是iOS捕获用户事件的各种情况,以及内部封装的一些特殊事件。我们先从UIButton谈起,UIButton大家使用的太多了,他特殊的地方就在于其内置的普通Default/高亮Highlighted/选择Selected/可用Enable的几个状态(UIControlState)。其次就是SDK内部已经为我们封装了以下用户事件:最常用的莫过于TouchUpInside这个事件了,他代表:用户在按钮区域内按下,并且也在按钮区域内松开。关键点:按下并且松开才能触发此方法,也就是正确的操作按下一次,松开一次只会触发一次此事件。与之不同的TouchDragInside等方法不需要松开这个过程,Up变为了Drag,其实大家都能理解,SDK在封装的时候原理跟UITouchEvent是一个道理,第一个单词Touch代表按下(Began)第二个单词Up代表松开(Ended),Drag代表拖动(Moved)。TouchMoved方法在一次完整的触摸中会被触发很多次,所以TouchDragInside方法会在用户手松开之前一直被触发。这些就是UIButton已封装的事件,而UIButton继承自UIControl。UIControl又继承自UIView。我们平时能用这些已封装的事件的控件都是UIControl的子类。那么父类UIView是没有内部事件的。我们常常利用UIView来写自己的UITouchEvent。例如在一个View/ViewController中直接实现以下3个方法:-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{}-(void)touchesMoved:(NSSet*)toucheswithEvent:(UIEvent*)event{}-(void)touchesEnded:(NSSet*)toucheswithEvent:(UIEvent*)event{}-(void)touchesCancelled:(NSSet*)toucheswithEvent:(UIEvent*)event{}-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event
{
}
-(void)touchesMoved:(NSSet*)toucheswithEvent:(UIEvent*)event
{
}
-(void)touchesEnded:(NSSet*)toucheswithEvent:(UIEvent*)event
{
}
-(void)touchesCancelled:(NSSet*)toucheswithEvent:(UIEvent*)event
{
}我们用的非常多,但是大家知道这4个方法是谁的实例方法吗?如果你一下就说出是UIView的,那么为什么我们在UIViewController中也可以用呢,他们不是继承关系。注意这4个实例方法来自UIView与UIViewController的共同父类:UIResponder。它是我们今天的主角。基本上我们所能看到的所有图形界面都是继承自UIResponder的,So,它究竟为何方神圣?UIResponder所谓很多视图的父类,他掌管着用户的操作事件分发大权。如果没有他,我们的电容屏如何将用户的操作传递给我们的视图令其做出反应呢?我们先看看iOS中的响应者链的概念:每一个应用有一个响应者链,我们的视图结构是一个N叉树(一个视图可以有多个子视图,一个子视图同一时刻只有一个父视图),而每一个继承UIResponder的对象都可以在这个N叉树中扮演一个节点。当叶节点成为最高响应者的时候,从这个叶节点开始往其父节点开始追朔出一条链,那么对于这一个叶节点来讲,这一条链就是当前的响应者链。响应者链将系统捕获到的UIEvent与UITouch从叶节点开始层层向下分发,期间可以选择停止分发,也可以选择继续向下分发。例子:我用SingleView模板创建了一个新的工程,它的主Window上只有一个UIViewController,其View之上有一个Button。这个项目中所有UIResponder的子类所构成的N叉树为这样的结构:那么他看起来并不像N叉树,但是不代表者不是一颗N叉树,当我们项目复杂之后,这个View可不可以有多个UIButton节点?所以他就是一棵树。实际上我们要把这棵树写完整,应该还要算上UIButton的UILabel和UIImageView,因为他们也是UIReponder的子类。这里先不考虑了。我们对UIButton来讲,他此时若是叶节点,那么这时我们针对他所在的响应链来说,他在他之前的响应者就应该是我们controller的view(树中的叶节点比父节点永远更优先被分发事件,但是并不是说他就能在时间上先响应,我们下面讲为什么)。所以我们尝试在任意地方打印这个Button的nextReponder对象。nextResponder对象是UIReponder类的实例方法,它会返回任意对象在树中的上一个响应者实例:NSLog(@"%@",_testButton.nextResponder);NSLog(@"%@",_testButton.nextResponder);2013-09-2103:40:25.989响应链[614:60b]<UIView:0x16555e10;frame=(00;320568);autoresize=RM+BM;layer=<CALayer:0x16555e70>>我们可以根据这个UIView的尺寸来得知,他就是我们唯一的控制器中的那个UIView。接下来我们再打印下这个UIView的下一个响应者是谁:NSLog(@"%@",_testButton.nextResponder.nextResponder);NSLog(@"%@",_testButton.nextResponder.nextResponder);2013-09-2103:45:03.914响应链[621:60b]<RSViewController:0x15da0e30>依次看,接着加一个nextResponder:2013-09-2103:50:49.428响应链[669:60b](null)注意这句代码我是写在ViewDidLoad中,而我们知道这个方法的生命周期比较早,所以我们换个地方写或者延迟一段时间再打印,两种方法都可以得到结果(由此可以推理出我们响应者树的构造过程是在ViewDidLoad周期中来完成的,这个函数会将当前实例的构成的响应者子树合并到我们整个根树中):2013-09-2103:53:47.304响应链[681:60b]<UIWindow:0x14e24200;frame=(00;320568);gestureRecognizers=<NSArray:0x14e242e0>;layer=<UIWindowLayer:0x14e244a0>>doubledelayInSeconds=2.0;dispatch_time_tpopTime=dispatch_time(DISPATCH_TIME_NOW,(int64_t)(delayInSeconds*NSEC_PER_SEC));dispatch_after(popTime,dispatch_get_main_queue(),^(void){NSLog(@"%@",_testButton.nextResponder.nextResponder.nextResponder.nextResponder);});doubledelayInSeconds=2.0;
dispatch_time_tpopTime=dispatch_time(DISPATCH_TIME_NOW,(int64_t)(delayInSeconds*NSEC_PER_SEC));
dispatch_after(popTime,dispatch_get_main_queue(),^(void){
NSLog(@"%@",_testButton.nextResponder.nextResponder.nextResponder.nextResponder);
});
2013-09-2103:56:22.043响应链[690:60b]<UIApplication:0x15659c00>2013-09-2103:56:51.186响应链[696:60b]<RSAppDelegate:0x16663520>2013-09-2103:57:22.588响应链[706:60b](null)这个树形结构在我们的项目中尤为重要,举个栗子,如果我们想在一个view中重写UITouchEvent的4个方法,并且不影响他的父视图也响应这些事件,就要注意你重写的方式了,比如我们在ViewController中重写touchBegan如下:-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{NSLog(@"ViewController接收到触摸事件");}-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event
{
NSLog(@"ViewController接收到触摸事件");
}-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{NSLog(@"appDelegate接收到触摸事件");}-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event
{
NSLog(@"appDelegate接收到触摸事件");
}那么究竟是谁被触发呢?2013-09-2104:02:49.405响应链[743:60b]ViewController接收到触摸事件-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{[supertouchesBegan:toucheswithEvent:event];NSLog(@"ViewController接收到触摸事件");}-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event
{
[supertouchesBegan:toucheswithEvent:event];
NSLog(@"ViewController接收到触摸事件");
}2013-09-2104:07:26.206响应链[749:60b]appDelegate接收到触摸事件2013-09-2104:07:26.208响应链[749:60b]ViewController接收到触摸事件那么我们分析一下这里的响应者链是怎样工作的:用户手指触摸到了UIView上,由于我们没有重写UIView的UITouchEvent,所以他里面和super执行的一样的,将该事件继续分发到UIViewController;UIViewController的TouchBegan被我们重写了,如果我们不super,那么我们在这里写响应代码。事件到这里就不继续分发了。可想而知,UIViewController祖先节点:UIWindow
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 荆州2025年湖北孝感市事业单位医疗类岗位引进招聘261人笔试历年参考题库附带答案详解
- 湛江广东湛江市第十中学2025年春季招聘编外教师笔试历年参考题库附带答案详解
- 营养支持联合运动训练对血液透析患者疲乏与衰弱干预效果研究
- 胱抑素C临床意义
- 工行业务介绍
- 小鸭子少儿课件
- 三年级英语下册 第5单元 课件 U5-L3-Lesson 3 Its Not Very Cold Here
- 苟建华在工作流程
- 2025年消防队伍建设与管理培训考试题库:消防安全知识与队伍建设案例分析
- 2025年统计学专业期末考试题库-基础概念题库解析与高分攻略试题
- 《油气储存企业安全风险评估细则(2025年修订版)》解读与培训
- 2025年安徽职业技术学院单招职业适应性测试题库汇编
- 2025年内蒙古北方职业技术学院单招职业倾向性测试题库完美版
- Deepseek 学习手册分享
- 护理新知识小讲课
- 电网工程设备材料信息参考价(2024年第四季度)
- 2024年全国职业院校技能大赛(新材料智能生产与检测赛项)考试题库(含答案)
- 《你当像鸟飞往你的山》读书分享读书分享笔记
- 2025云南红河州个旧市大红屯粮食购销限公司招聘及人员高频重点提升(共500题)附带答案详解
- 二级营销员模拟考试题(含答案)
- 2024-2030年北京古玩行业竞争格局及投资经营状况分析报告
评论
0/150
提交评论