当发生事件响应的时候,必须知道由谁来响应事件.在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连锁链)的更多相关文章

  1. iOS事件传递和事件响应者链 20170810

    一.事件响应者链 事件传递和事件响应链 区别 事件的传递和响应的区别: 事件的传递是从上到下(父控件到子控件),事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件. 引出 当我们手指触摸屏幕 ...

  2. iOS 之 事件响应者链

    响应者链表示一系列的响应者对象.事件被交由第一个响应者对象处理,如果第一个响应者不处理,事件就沿着响应者链向上传递,交由下一个响应者(Next responder). View->ViewCon ...

  3. iOS事件响应链

    首先,当发生事件响应时,必须知道由谁来响应事件.在IOS中,由响应者链来对事件进行响应,所有事件响应的类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获 ...

  4. Responder一点也不神秘————iOS用户响应者链完全剖析

    一.事件分类 对于IOS设备用户来说,他们操作设备的方式主要有三种:触摸屏幕.晃动设备.通过遥控设施控制设备.对应的事件类型有以下三种: 1.触屏事件(Touch Event) 2.运动事件(Moti ...

  5. [置顶] Responder一点也不神秘————iOS用户响应者链完全剖析

    这篇文章想跟大家分享的主旨是iOS捕获用户事件的各种情况,以及内部封装的一些特殊事件. 我们先从UIButton谈起,UIButton大家使用的太多了,他特殊的地方就在于其内置的普通Default/高 ...

  6. iOS用户响应者链的那些事儿

    这篇文章想跟大家分享的主旨是iOS捕获用户事件的各种情况,以及内部封装的一些特殊事件. 我们先从UIButton谈起,UIButton大家使用的太多了,他特殊的地方就在于其内置的普通Default/高 ...

  7. iOS事件响应链(Responder Chain)

    概述 在iOS中,视图的层级一般都是 父视图->添加各种子视图.这时候某个视图(子视图)上有个按钮,需要我们交互.但是有时候我们会发现无论如何都没有反应.这时候可能就是我们对iOS的事件传递响应 ...

  8. iOS响应者链和事件传递机制

    原文来自:http://www.cnblogs.com/zhw511006/p/3517248.html 响应者链(Responder Chain) 通常,一个iOS应用中,在一块屏幕上通常有很多的U ...

  9. iOS事件传递->处理->响应

    前言: 按照时间顺序,事件的生命周期是这样的: 事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view.寻找最合适的view的底层实现.拦截事件的处理)->找到最合适的view后 ...

随机推荐

  1. hmtl表单

    表单: <form id="" name="" method="post/get" action="负责处理的服务端&quo ...

  2. sscanf()的用法

    头文件 #include 定义函数 int sscanf (const char *str,const char * format,........); 函数说明             sscanf ...

  3. 也许,这样理解HTTPS更容易_转载

    转自:也许,这样理解HTTPS更容易 原文衔接:https://showme.codes/2017-02-20/understand-https/ 作者:翟志军  摘要 本文尝试一步步还原HTTPS的 ...

  4. plsql programming 14 DML和事务管理

    我们可以把多个SQL语句集中在一起, 在逻辑上组成一个事务, 从而保证这些操作或者全部被保存到数据库(用sql的说法就是”提交”), 或者被整体驳回(用sql的说法是“回滚”). 事务: ACID 原 ...

  5. Package java.sql

    Provides the API for accessing and processing data stored in a data source (usually a relational dat ...

  6. (转载)将一段符合XML格式规范字符串插入已有XML文档当中

    想我们已经存在一个XML文档,结构如下:   < xmlversion="1.0"encoding="utf-8">< employees&g ...

  7. 目前国际上所用云计算平台IaaS、PaaS、SaaS简介

    随着云计算这个概念越来越为人所熟知,企业对云计算的重视程度也在日趋加深.这不仅是一种潮流,更体现了一种需求——数字化.现代化.科技化的整体需求.如今市场上云计算的运营商更是风起云涌,服务种类更是丰富繁 ...

  8. Gallery学习————检测手机中是否存在外部存储设备

    在缓存数据的时,有时候会出现没有外部存储设备的情况,所以需要检测是否存在外部存储设备 /** * 检测外部存储设备 * * @param requireWriteAccess * @return */ ...

  9. GoogleMap-------Google Play services SDK的下载和配置

    前言:在android开发项目中当要使用GoogleMap需要有Google Maps Android API的支持,而他包含在了Google Play services SDK中,所以本文将介绍如何 ...

  10. python3----练习题(三级菜单)

    三级菜单程序. 运行程序输出第一级菜单. 选择一级菜单某项,输出二级菜单,同理输出三级菜单. 退出时返回上一级菜单 menu = { '北京市': { '东城区': { 'aa', 'bb', }, ...