事件的響應(yīng)鏈條

Understanding Event Handling, Responders, and the Responder Chain。

了解事件處理,響應(yīng)者以及響應(yīng)者鏈。

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

學(xué)會(huì)事件在你的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用響應(yīng)對(duì)象來(lái)接收和處理事件。響應(yīng)對(duì)象是UIResponder類(lèi)的任何一個(gè)實(shí)例,普通的子類(lèi)包括UIView,UIViewController, 和UIApplication。響應(yīng)者接收到原始事件數(shù)據(jù)后,必須要么處理這個(gè)事件,要么轉(zhuǎn)發(fā)給另一個(gè)響應(yīng)者對(duì)象。當(dāng)你的APP接收到一個(gè)事件的時(shí)候,UIKit會(huì)自動(dòng)把事件指給最合適的響應(yīng)者對(duì)象,稱(chēng)為第一響應(yīng)者。在響應(yīng)鏈條上,未處理的事件被傳遞從一個(gè)響應(yīng)者到另一個(gè)響應(yīng)者,這是你的APP響應(yīng)者對(duì)象中的一個(gè)動(dòng)態(tài)結(jié)構(gòu)。你的程序沒(méi)有單一響應(yīng)者鏈。UIKit定義了一套默認(rèn)的關(guān)于一個(gè)響應(yīng)者是怎樣傳遞給下一個(gè)響應(yīng)者的規(guī)則。但是,你也可以通過(guò)重寫(xiě)響應(yīng)者對(duì)象合適的屬性來(lái)改變這個(gè)規(guī)則。下圖展示了在一個(gè)APP的交互包括a label, a text field, a button, 和 two background views的默認(rèn)響應(yīng)者鏈。如果text field不能處理事件,UIKit將會(huì)發(fā)送時(shí)間給它的text field的父視圖,緊接著是這個(gè)窗口的根視圖。從這個(gè)根視圖開(kāi)始,響應(yīng)者鏈在傳到window之前會(huì)轉(zhuǎn)到自己的控制器。如果window也不能處理這個(gè)事件,UIKit會(huì)把事件傳遞給UIApplication對(duì)象,也可能到達(dá)app delegate。如果這個(gè)對(duì)象不是UIResponder的實(shí)例,將不會(huì)稱(chēng)為響應(yīng)鏈的一部分。


響應(yīng)鏈

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.

對(duì)于沒(méi)類(lèi)型事件,UIKit都會(huì)指定第一響應(yīng)者,首先發(fā)送事件到這個(gè)對(duì)象。第一響應(yīng)者基于事件的類(lèi)型而不同。

Touch events

觸摸事件

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

第一響應(yīng)者是你觸摸的那個(gè)視圖。

Press events

按壓事件

The first responder is the responder that has focus.

第一響應(yīng)者是按壓的響應(yīng)者。

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消息與和控件結(jié)合的target對(duì)象進(jìn)行交流。當(dāng)用戶和控件交流的時(shí)候,控件會(huì)調(diào)用target對(duì)象的action方法。換句話說(shuō),控件會(huì)發(fā)送action消息給target對(duì)象。Action消息不是事件,但是action一直利用響應(yīng)鏈。當(dāng)控件的target對(duì)象是nil的時(shí)候,UIKit會(huì)從target對(duì)象開(kāi)始,沿著響應(yīng)者鏈,直到發(fā)現(xiàn)一個(gè)對(duì)象,它實(shí)現(xiàn)了合適的action方法。例如,UIKit編輯按鈕利用這種行為來(lái)搜索實(shí)現(xiàn)了剪切,復(fù)制,粘貼方法的響應(yīng)者。

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.

如果給一個(gè)視圖添加了一個(gè)手勢(shì),那么在視圖接收到它們之前,手勢(shì)會(huì)收到觸摸事件。如果一個(gè)視圖的所有手勢(shì)都不能響應(yīng)這個(gè)手勢(shì),那么事件會(huì)傳遞給視圖進(jìn)行處理。如果視圖不能處理事件,UIKit傳遞這個(gè)事件到響應(yīng)鏈。

Determining Which Responder Contained a Touch Event

決定哪一個(gè)響應(yīng)者包含觸摸事件。

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方法來(lái)決定觸摸事件發(fā)生在哪里。具體來(lái)說(shuō),在視圖層次上,UIKit將觸摸位置和視圖對(duì)象的邊界進(jìn)行比較。視圖的hitTest(_:with:)方法來(lái)查找包含觸摸點(diǎn)的最深的子視圖。

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.

如果一個(gè)觸摸點(diǎn)在一個(gè)視圖的邊界外邊,那么,hitTest(_:with:)方法會(huì)忽略那個(gè)視圖和所有的子視圖。因此,當(dāng)一個(gè)視圖的clipsToBounds屬性是false的時(shí)候,子視圖在視圖外邊是不能返回的,盡管視圖包含觸摸事件。

注意:查找觸摸點(diǎn)的時(shí)候是以bounds為標(biāo)準(zhǔn)進(jìn)行查找的。

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會(huì)永久分配每個(gè)觸摸到包含它的視圖。當(dāng)觸摸事件發(fā)生的時(shí)候,UIKit創(chuàng)建UITouch對(duì)象。當(dāng)觸摸結(jié)束的之后,它會(huì)release掉這個(gè)對(duì)象。當(dāng)觸摸位置改變或者參數(shù)發(fā)生改變的時(shí)候,UIKit會(huì)用新信息更新UITouch對(duì)象。僅有的屬性不會(huì)發(fā)生變化的是包含的視圖。盡管當(dāng)觸摸位置移動(dòng)到原始位置之外,觸摸的視圖屬性并不會(huì)發(fā)生變化。

Altering the Responder Chain

變更響應(yīng)者鏈

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.

你可以通過(guò)重寫(xiě)響應(yīng)對(duì)象的下一個(gè)屬性來(lái)改變響應(yīng)者鏈。當(dāng)你這樣做之后,下一個(gè)響應(yīng)者鏈僵尸你返回的那個(gè)。

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

大多數(shù)UIKit類(lèi)總是重寫(xiě)這個(gè)屬性,返回特定的對(duì)象。

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對(duì)象:如果這個(gè)視圖是控制器的根view,下一個(gè)響應(yīng)者就是控制器。否則,下個(gè)響應(yīng)者是這個(gè)使徒的父視圖。

UIViewController?objects

控制器對(duì)象

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

如果這個(gè)控制器的視圖是窗口的根視圖,下一個(gè)響應(yīng)者是window對(duì)象。

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

如果這個(gè)控制器由另一個(gè)控制器呈現(xiàn),下一個(gè)響應(yīng)者是這個(gè)呈現(xiàn)控制器。

UIWindow?objects

窗口對(duì)象

The window's next responder is the?UIApplication?object.

窗口的想一個(gè)響應(yīng)者是UIApplication。

UIApplication?object:

UIApplication對(duì)象

?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的下一個(gè)響應(yīng)者是UIApplication的代理,但是只有這個(gè)代理是UIResponder的實(shí)例,不是view,控制器,APP本身。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的?困惑于Cell怎么突然不能點(diǎn)擊了?糾結(jié)于如何實(shí)現(xiàn)這個(gè)奇葩響應(yīng)需求?亦或是...
    Lotheve閱讀 59,626評(píng)論 51 604
  • 在iOS開(kāi)發(fā)中經(jīng)常會(huì)涉及到觸摸事件。本想自己總結(jié)一下,但是遇到了這篇文章,感覺(jué)總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載。作者:L...
    WQ_UESTC閱讀 6,251評(píng)論 4 26
  • 用戶以多種方式操縱他們的iOS設(shè)備,例如觸摸屏幕或搖動(dòng)設(shè)備。 iOS會(huì)解釋用戶何時(shí)以及如何操作硬件并將此信息傳遞到...
    坤坤同學(xué)閱讀 4,137評(píng)論 7 19
  • 一. Hit-Testing 什么是Hit-Testing?對(duì)于觸摸事件, window首先會(huì)嘗試將事件交給事件觸...
    面糊閱讀 1,048評(píng)論 0 50
  • -- iOS事件全面解析 概覽 iPhone的成功很大一部分得益于它多點(diǎn)觸摸的強(qiáng)大功能,喬布斯讓人們認(rèn)識(shí)到手機(jī)其實(shí)...
    翹楚iOS9閱讀 3,229評(píng)論 0 13

友情鏈接更多精彩內(nèi)容