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后 ...
随机推荐
- springMVC集成mybatis-paginator实现分页
mybatis-paginator下载地址:https://github.com/miemiedev/mybatis-paginator 1.引入maven依赖 <dependency> ...
- Sublime 中 SFTP插件的使用
首先说明的是Sumblime Text 3,下载安装后,打开软件, 按下Ctrl+Shift+P调出命令面板, 按回车键后弹出下面的 然后 点击左上角的 文件 >SFTP/FTP > Se ...
- 介绍两款Linux文件恢复工具,ext3grep与extundelete https://www.cnblogs.com/lazyfang/p/7699994.html
介绍两款Linux文件恢复工具,ext3grep与extundelete,可能在关键时刻会有所帮助.ext3grep仅对ext3文件系统有效,extundelete对ext3与ext4文件系统都有效 ...
- 导入mysql文件提示“ASCII '\0' appeared in the statement”
在windows服务器上导入mysql文件时,出现以下报错:ASCII '\0' appeared in the statement, but this is not allowed unless o ...
- Android.mk 输出日志 调试
$(warning "the value of MY_FILES_PATH is $(MY_FILES_PATH)") #jni
- 进出口流程 & 报关单据
出口流程 一. 委托人 1. 需找货运代理公司 2. 向代理公司询问价格 一般为 ALL IN 价格( 空运费+燃油费+战险费 ) 总费用 = ALL IN 价格 * ( 货物公斤数 ) ALL IN ...
- [ JS 进阶 ] 基本类型 引用类型 简单赋值 对象引用 (转)
ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型.也有其他的叫法,比如原始类型和对象类型,拥有方法的类型和不能拥有方法的类型,还可以分为可变类型和不可变类型,其实这些叫法都是依据这两 ...
- lumen-Permission 权限管理使用心得
安装 composer require spatie/laravel-permission github上有详细介绍:https://github.com/spatie/laravel-permiss ...
- 第10章 Docker Machine 相关问题
10.1 打开命令行后,看到下载啥 boot2docker.iso,然后总是超时失败,怎么办? 装了 Docker Toolbox 的 Windows 用户,或者第一次使用 docker-machin ...
- 使用jenkins进行Android的持续集成
关于持续集成的定义和意义可以参考它的 百度百科 主要意义有以下几点: 减少风险 减少重复过程 任何时间.任何地点生成可部署的软件 增强项目的可见性 建立团队对开发产品的信心 持续集成的实施 持续集成的 ...