事件的响应链条

Understanding Event Handling, Responders, and the Responder Chain。

了解事件处理,响应者以及响应者链。

Learn how events are propagated through your app and how you handle them.

学会事件在你的APP中是怎样传递以及你怎样处理它们。

Overview

综述

Apps receive and handle events using responder objects. A responder object is any instance of the UIResponder class, and common subclasses include UIView,UIViewController, andUIApplication. Responders receive the raw event data and must either handle the event or forward it to another responder object. When your app receives an event, UIKit automatically directs that event to the most appropriate responder object, known as thefirst responder. Unhandled events are passed from responder to responder in the active responder chain, which is a dynamic configuration of your app’s responder objects. There is no single responder chain within your app. UIKit defines default rules for how objects are passed from one responder to the next, but you can always change those rules by overriding the appropriate properties in your responder objects.Figure 1shows the default responder chains in an app whose interface contains a label, a text field, a button, and two background views. If the text field does not handle an event, UIKit sends the event to the text field’s parentUIView object, followed by the root view of the window. From the root view, the responder chain diverts to the owning view controller before directing the event to the window. If the window does not handle the event, UIKit delivers the event to the UIApplication object, and possibly to the app delegate if that object is an instance of UIResponder and not already part of the responder chain.

APP用响应对象来接收和处理事件。响应对象是UIResponder类的任何一个实例,普通的子类包括UIView,UIViewController, 和UIApplication。响应者接收到原始事件数据后,必须要么处理这个事件,要么转发给另一个响应者对象。当你的APP接收到一个事件的时候,UIKit会自动把事件指给最合适的响应者对象,称为第一响应者。在响应链条上,未处理的事件被传递从一个响应者到另一个响应者,这是你的APP响应者对象中的一个动态结构。你的程序没有单一响应者链。UIKit定义了一套默认的关于一个响应者是怎样传递给下一个响应者的规则。但是,你也可以通过重写响应者对象合适的属性来改变这个规则。下图展示了在一个APP的交互包括a label, a text field, a button, 和 two background views的默认响应者链。如果text field不能处理事件,UIKit将会发送时间给它的text field的父视图,紧接着是这个窗口的根视图。从这个根视图开始,响应者链在传到window之前会转到自己的控制器。如果window也不能处理这个事件,UIKit会把事件传递给UIApplication对象,也可能到达app delegate。如果这个对象不是UIResponder的实例,将不会称为响应链的一部分。


响应链

Determining the First Responder for an Event

For every type of event, UIKit designates a first responder and sends the event to that object first. The first responder varies based on the type of event.

对于没类型事件,UIKit都会指定第一响应者,首先发送事件到这个对象。第一响应者基于事件的类型而不同。

Touch events

触摸事件

The first responder is the view in which the touch occurred.

第一响应者是你触摸的那个视图。

Press events

按压事件

The first responder is the responder that has focus.

第一响应者是按压的响应者。

Controls communicate directly with their associated target object using action messages. When the user interacts with a control, the control calls the action method of its target object—in other words, it sends an action message to its target object. Action messages are not events, but they may still take advantage of the responder chain. When the target object of a control is nil, UIKit starts from the target object and walks the responder chain until it finds an object that implements the appropriate action method. For example, the UIKit editing menu uses this behavior to search for responder objects that implement methods with names likecut(_:),copy(_:), orpaste(_:).

控件直接使用action消息与和控件结合的target对象进行交流。当用户和控件交流的时候,控件会调用target对象的action方法。换句话说,控件会发送action消息给target对象。Action消息不是事件,但是action一直利用响应链。当控件的target对象是nil的时候,UIKit会从target对象开始,沿着响应者链,直到发现一个对象,它实现了合适的action方法。例如,UIKit编辑按钮利用这种行为来搜索实现了剪切,复制,粘贴方法的响应者。

If a view has an attached gesture recognizer, the gesture recognizer receives touch and press events before the view receives them. If all of the view’s gesture recognizers fail to recognize their gestures, the events are passed to the view for handling. If the view does not handle them, UIKit passes the events up the responder chain. For more information about using gesture recognizer’s to handle events, seeHandling UIKit Gestures.

如果给一个视图添加了一个手势,那么在视图接收到它们之前,手势会收到触摸事件。如果一个视图的所有手势都不能响应这个手势,那么事件会传递给视图进行处理。如果视图不能处理事件,UIKit传递这个事件到响应链。

Determining Which Responder Contained a Touch Event

决定哪一个响应者包含触摸事件。

UIKit uses view-based hit-testing to determine where touch events occur. Specifically, UIKit compares the touch location to the bounds of view objects in the view hierarchy. The hitTest(_:with:) method of UIView walks the view hierarchy, looking for the deepest subview that contains the specified touch. That view becomes the first responder for the touch event.

UIKit利用基view的hit-testing方法来决定触摸事件发生在哪里。具体来说,在视图层次上,UIKit将触摸位置和视图对象的边界进行比较。视图的hitTest(_:with:)方法来查找包含触摸点的最深的子视图。

Note

注意:

If a touch location is outside of a view’s bounds, the hitTest(_:with:)method ignores that view and all of its subviews. As a result, when a view’s clipsToBounds property is false, subviews outside of that view’s bounds are not returned even if they happen to contain the touch. For more information about the hit-testing behavior, see the discussion of thehitTest(_:with:)method inUIView.

如果一个触摸点在一个视图的边界外边,那么,hitTest(_:with:)方法会忽略那个视图和所有的子视图。因此,当一个视图的clipsToBounds属性是false的时候,子视图在视图外边是不能返回的,尽管视图包含触摸事件。

注意:查找触摸点的时候是以bounds为标准进行查找的。

UIKit permanently assigns each touch to the view that contains it. UIKit creates each UITouch object when the touch first occurs, and it releases that touch object only after the touch ends. As the touch location or other parameters change, UIKit updates theUITouchobject with the new information. The only property that does not change is the containing view. Even when the touch location moves outside the original view, the value in the touch’sviewproperty does not change.

UIKit会永久分配每个触摸到包含它的视图。当触摸事件发生的时候,UIKit创建UITouch对象。当触摸结束的之后,它会release掉这个对象。当触摸位置改变或者参数发生改变的时候,UIKit会用新信息更新UITouch对象。仅有的属性不会发生变化的是包含的视图。尽管当触摸位置移动到原始位置之外,触摸的视图属性并不会发生变化。

Altering the Responder Chain

变更响应者链

You can alter the responder chain by overriding thenextproperty of your responder objects. When you do this, the next responder is the object that you return.

你可以通过重写响应对象的下一个属性来改变响应者链。当你这样做之后,下一个响应者链僵尸你返回的那个。

Many UIKit classes already override this property and return specific objects.

大多数UIKit类总是重写这个属性,返回特定的对象。

UIView objects:

 If the view is the root view of a view controller, the next responder is the view controller; otherwise, the next responder is the view’s superview.

UIView对象:如果这个视图是控制器的根view,下一个响应者就是控制器。否则,下个响应者是这个使徒的父视图。

UIViewController objects

控制器对象

If the view controller’s view is the root view of a window, the next responder is the window object.

如果这个控制器的视图是窗口的根视图,下一个响应者是window对象。

If the view controller was presented by another view controller, the next responder is the presenting view controller.

如果这个控制器由另一个控制器呈现,下一个响应者是这个呈现控制器。

UIWindow objects

窗口对象

The window's next responder is the UIApplication object.

窗口的想一个响应者是UIApplication

UIApplication object:

UIApplication对象

 The next responder is the app delegate, but only if the app delegate is an instance of UIResponder and is not a view, view controller, or the app object itself.

UIApplication的下一个响应者是UIApplication的代理,但是只有这个代理是UIResponder的实例,不是view,控制器,APP本身。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 好奇触摸事件是如何从屏幕转移到APP内的?困惑于Cell怎么突然不能点击了?纠结于如何实现这个奇葩响应需求?亦或是...
    Lotheve阅读 56,567评论 51 597
  • 在iOS开发中经常会涉及到触摸事件。本想自己总结一下,但是遇到了这篇文章,感觉总结的已经很到位,特此转载。作者:L...
    WQ_UESTC阅读 5,987评论 4 26
  • 用户以多种方式操纵他们的iOS设备,例如触摸屏幕或摇动设备。 iOS会解释用户何时以及如何操作硬件并将此信息传递到...
    坤坤同学阅读 3,975评论 7 19
  • 一. Hit-Testing 什么是Hit-Testing?对于触摸事件, window首先会尝试将事件交给事件触...
    面糊阅读 814评论 0 50
  • -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实...
    翘楚iOS9阅读 2,938评论 0 13