iOS 事件响应者链的学习(也有叫 UI连锁链)
当发生事件响应的时候,必须知道由谁来响应事件.在iOS中,由响应链来对事件进行响应,所有的事件响应的类都是继承于UIResponder的子类,响应链是一个由不同对象组成的层次结构,其中每个对象将依次获得响应事件消息的机会
发生触摸事件后,系统将事件加入到由UIApplication管理的事件 队列
好处:遵循第一响应原则,总会优先处理队列中排在最前面的事件.(栈是先进后出 不符合业务逻辑)
(1)事件传递(链)
1.传递链中时没有controller的,因为controller本身不具有大小的概念
2.用户的触摸事件首先会由系统截获,进行包装处理等。然后递归遍历所有的view,进行碰触测试(hitTest),直到找到可以处理事件的view
大致的过程application –> window –> root view –>……–>lowest view
网上一个很直观的解释图

(2)响应链
1.响应链中是有controller的,因为controller继承自UIResponder
2.当有view能够处理触摸事件后,开始响应事件。
系统会调用view的以下方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
可以多对象共同响应事件。只需要在以上方法重载中调用super的方法。
大致的过程initial view –> super view –> …..–> view controller –> window –> Application
我记得 前年被一位CTO面试的时候 问到过这个问题 ,原话大概是说”触发一个按钮,怎么截获 它的触发消息”;当时说得一塌糊涂 ,但是由于 有个创意性的问题分析回答得特别到位 ,还夸奖了我,说我有想法,他还感冒了,说要去擤鼻子 然后就没在回来 .比较遗憾的面试,其实不要估计我是女生呀,我不怕拒绝,也没说原因呢,就没有然后了.
现在想起来,估计这个”事件传递响应者链”的原理真的很重要,如今学习的更加深入,自然而然就会去讨论学习,在开发中运用起来. 真是成长如蜕啊.
举例:
其实开发中,真的好多地方可以运用到这个方法,用来截获一些信息啦,处理消息,获取对象,修改响应,或者具体知道自己实现一个方法到底该是怎样一个流程等.
需求:在cell上添加一个按钮,点击一下进入下一个导航页面.
之前通常的做法是,” [cell.btn addTarget: blabla ]” 写在视图控制器里面 ,因为这样很好的调用到viewController.
现在知道了事件响应者链的原理 就利用这个机制解决一下吧
2.1首先创建一个UIView 类别 扩展 一个实例方法 根据"事件响应者链原理" :判读UIView上的点击事件,如果已经传递到了UIViewController,则就进行处理。获取这个视图控制器.
//
// UIView+EventLink.h
// TableViewDemo
//
// Created by HF on 16/2/26.
// Copyright © 2016年 HF-zhjh. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (EventLink)
-(UIViewController *)viewController;
@end //
// UIView+EventLink.m
// TableViewDemo
//
// Created by HF on 16/2/26.
// Copyright © 2016年 HF-zhjh. All rights reserved.
// #import "UIView+EventLink.h"
@implementation UIView (EventLink)
//为UIView扩展一个方法,用于响应事件链
-(UIViewController *)viewController{
UIResponder *nexRes=[self nextResponder];
do {
//判读当前的响应者是否UIViewController
if ([nexRes isKindOfClass:[UIViewController class]]) {
//是否直接处理
return (UIViewController*)nexRes;
}else{
//否则继续寻找
nexRes=[nexRes nextResponder];
}
} while (nexRes!=nil);
return nil;
}
@end
通过为UIView扩展一个分类(类别)方法之后,我们就可以在Cell中调用分类方法(viewController)处理事件响应了。
//按钮事件
//UITableViewCell 继承于UIView 所以 现在 cell 多了一个属性 就是 viewController 可以直接用了
//其实还算是很方便 可读性也很高
-(void)buttonAction:(UIButton *)btn{
//使用事件响应者
UIViewController *view=[[UIViewController alloc] init];
[self.viewController.navigationController pushViewController:view animated:YES];
[view release];
}
(3)几种无法接受触摸事件的情况
1.不接收用户交互
userInteractionEnabled = NO
2.隐藏
hidden = YES
3.透明
alpha = 0.0 ~ 0.01
提示:UIImageView的userInteractionEnabled默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的
iOS 事件响应者链的学习(也有叫 UI连锁链)的更多相关文章
- iOS事件传递和事件响应者链 20170810
一.事件响应者链 事件传递和事件响应链 区别 事件的传递和响应的区别: 事件的传递是从上到下(父控件到子控件),事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件. 引出 当我们手指触摸屏幕 ...
- iOS 之 事件响应者链
响应者链表示一系列的响应者对象.事件被交由第一个响应者对象处理,如果第一个响应者不处理,事件就沿着响应者链向上传递,交由下一个响应者(Next responder). View->ViewCon ...
- iOS事件响应链
首先,当发生事件响应时,必须知道由谁来响应事件.在IOS中,由响应者链来对事件进行响应,所有事件响应的类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获 ...
- Responder一点也不神秘————iOS用户响应者链完全剖析
一.事件分类 对于IOS设备用户来说,他们操作设备的方式主要有三种:触摸屏幕.晃动设备.通过遥控设施控制设备.对应的事件类型有以下三种: 1.触屏事件(Touch Event) 2.运动事件(Moti ...
- [置顶] Responder一点也不神秘————iOS用户响应者链完全剖析
这篇文章想跟大家分享的主旨是iOS捕获用户事件的各种情况,以及内部封装的一些特殊事件. 我们先从UIButton谈起,UIButton大家使用的太多了,他特殊的地方就在于其内置的普通Default/高 ...
- iOS用户响应者链的那些事儿
这篇文章想跟大家分享的主旨是iOS捕获用户事件的各种情况,以及内部封装的一些特殊事件. 我们先从UIButton谈起,UIButton大家使用的太多了,他特殊的地方就在于其内置的普通Default/高 ...
- iOS事件响应链(Responder Chain)
概述 在iOS中,视图的层级一般都是 父视图->添加各种子视图.这时候某个视图(子视图)上有个按钮,需要我们交互.但是有时候我们会发现无论如何都没有反应.这时候可能就是我们对iOS的事件传递响应 ...
- iOS响应者链和事件传递机制
原文来自:http://www.cnblogs.com/zhw511006/p/3517248.html 响应者链(Responder Chain) 通常,一个iOS应用中,在一块屏幕上通常有很多的U ...
- iOS事件传递->处理->响应
前言: 按照时间顺序,事件的生命周期是这样的: 事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view.寻找最合适的view的底层实现.拦截事件的处理)->找到最合适的view后 ...
随机推荐
- TCP/IP笔记(一)网络基础知识
计算机与网络发展 计算机自诞生伊始,经历了一系列演变与发展.大型通用机计算机.超级计算机.小型机.个人电脑.工作站.便携式电以及现如今的智能手机终端都是这一过程的产物.它们性能逐年增强,价格却逐年下降 ...
- CDH配置JAVA_HOME
jdk成功安装 java -version 正确显示版本 echo $JAVA_HOME 正确输出路径 但CDH链接数据库还是报错: Error: JAVA_HOME is not set and ...
- Spring 3 MVC and JSR303 @Valid example
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/ ———————————————————————————— ...
- 第一百七十九节,jQuery-UI,知问前端--按钮 UI-图标
jQuery-UI,知问前端--按钮 UI 学习要点: 1.使用 button 按钮 2.修改 button 样式 3.button()方法的属性 4.button('action', param) ...
- python __new__ __init__ __del__
1.python实例化顺序是.__new__ -->__init__ --> __del__ 2.如果重写new没return,就实例化不成功
- 安装onlyoffice document server
1. 安装docker apt install docker.io 2. 安装和启动onlyoffice sudo docker run -i -t -d -p 80:80 onlyoffice/do ...
- openstack组件通讯端口定义
openstack 组件通讯是通过ZeroMQ+ceilometer发送组件调用信息,具体是通过TCP通讯,发送数据和接收数据是用同一个端口(在配置文件指定),下面通过代码稍作解析: IceHouse ...
- hdu5334(2015多校4)--Virtual Participation(构造)
题目链接:pid=5334">点击打开链接 题目大意:给出一个数字k,要求做出一个长度小于等于10^5的序列.该序列中不同样的连续子序列有k个. 构造啊,.,,,,一点辙都没有 使用连 ...
- 数据库 : Mysql - 日常应用
#登录MYSQL数据库 MYSQL -u root -p #显示所有数据库 SHOW databases; #显示当前数据库与应用程序间进行了多少条连接 SHOW processlist; #使用某一 ...
- Unity3D学习笔记——NGUI之UIScrollBar
UIScrollBar:这个组件可以用于创建滚动条. 效果图如下: 一:使用步骤 1.这个组件和UISlider很像,也是由三部分组成. 2.首先创建一个Sprite用于组件的背景色. 3.创建第二个 ...