iOS觸摸事件的傳遞和響應(yīng)機(jī)制原理

事件層次分析圖

觸摸事件的處理原理如下:

1.當(dāng)用戶點擊屏幕時,會產(chǎn)生一個觸摸事件,系統(tǒng)會將該事件加入到一個由UIApplication管理的事件隊列中

2.UIApplication會從事件隊列中取出最前面的事件進(jìn)行分發(fā)以便處理,通常,先發(fā)送事件給應(yīng)用程序的主窗口(UIWindow)

3. 主窗口會調(diào)用hitTest:withEvent:方法在視圖(UIView)層次結(jié)構(gòu)中找到一個最合適的UIView來處理觸摸事件

(hitTest:withEvent:其實是UIView的一個方法,UIWindow繼承自UIView,因此主窗口UIWindow也是屬于視圖的一種)

4.hitTest:withEvent:方法大致處理流程是這樣的:

首先調(diào)用當(dāng)前視圖的pointInside:withEvent:方法判斷觸摸點是否在當(dāng)前視圖內(nèi):

若pointInside:withEvent:方法返回NO,說明觸摸點不在當(dāng)前視圖內(nèi),則當(dāng)前視圖的hitTest:withEvent:返回nil

若pointInside:withEvent:方法返回YES,說明觸摸點在當(dāng)前視圖內(nèi),則遍歷當(dāng)前視圖的所有子視圖(subviews),調(diào)用子視圖的hitTest:withEvent:方法重復(fù)前面的步驟,子視圖的遍歷順序是從top到bottom,即從subviews數(shù)組的末尾向前遍歷,直到有子視圖的hitTest:withEvent:方法返回非空對象或者全部子視圖遍歷完畢:

?若第一次有子視圖的hitTest:withEvent:方法返回非空對象,則當(dāng)前視圖的hitTest:withEvent:方法就返回此對象,處理結(jié)束

若所有子視圖的hitTest:withEvent:方法都返回nil,則當(dāng)前視圖的hitTest:withEvent:方法返回當(dāng)前視圖自身(self)

最終,這個觸摸事件交給主窗口的hitTest:withEvent:方法返回的視圖對象去處理。

拿到這個UIView后,就調(diào)用該UIView的touches系列方法。

5.消息處理過程,在找到的那個視圖里處理,處理完后根據(jù)需要,利用響應(yīng)鏈nextResponder可將消息往下一個響應(yīng)者傳遞。

UIAppliactionDelegate <- UIWindow <- UIViewController <- UIView <- UIView

【注意】:要理解的有三點:

1、iOS判斷哪個界面能接受消息是從View層級結(jié)構(gòu)的父View向子View傳遞,即樹狀結(jié)構(gòu)的根節(jié)點向葉子節(jié)點遞歸傳遞。

2、hitTest和pointInside成對,且hitTest會調(diào)用pointInside。

3、iOS的消息處理是,當(dāng)消息被人處理后默認(rèn)不再向父層傳遞。

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

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

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