由按鈕和圖片引發(fā)的事件傳遞血案

  • 如果在UIImageView中添加一個(gè)按鈕,如下圖
    按鈕作為圖片的子控件.png

    你會(huì)發(fā)現(xiàn),靠,按鈕點(diǎn)擊不了了,沒錯(cuò)確實(shí)是點(diǎn)擊按鈕不會(huì)有反應(yīng),因?yàn)閁IImageView默認(rèn)的userInteractionEnabled = NO.所以要想圖片中的按鈕被點(diǎn)擊需要設(shè)置
imageView.userInteractionEnabled = YES;

那這到底時(shí)什么原因了,點(diǎn)擊事件時(shí)怎么傳遞的呢,下面讓我們先看一張事件傳遞的示例圖:

事件傳遞例子.png

看了上圖之后可能對(duì)事件傳遞有了一定的了解,下面讓我再具體的分析一下事件傳遞的過程,過程如下:

  • 當(dāng)用戶點(diǎn)擊屏幕時(shí),會(huì)產(chǎn)生一個(gè)觸摸事件,系統(tǒng)會(huì)將該事件加入到一個(gè)由UIApplication管理的事件隊(duì)列中

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

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

    • hitTest:withEvent:其實(shí)是UIView的一個(gè)方法,UIWindow繼承自UIView,因此主窗口UIWindow也是屬于視圖的一種
  • hitTest:withEvent:方法大致處理流程是這樣的:

    • 首先調(diào)用當(dāng)前視圖的pointInside:withEvent:方法判斷觸摸點(diǎn)是否在當(dāng)前視圖內(nèi):
    • pointInside:withEvent:方法返回NO,說明觸摸點(diǎn)不在當(dāng)前視圖內(nèi),則當(dāng)前視圖的hitTest:withEvent:返回nil
    • pointInside:withEvent:方法返回YES,說明觸摸點(diǎn)在當(dāng)前視圖內(nèi),則遍歷當(dāng)前視圖的所有子視圖(subviews),調(diào)用子視圖的hitTest:withEvent:方法重復(fù)前面的步驟,子視圖的遍歷順序是從subviews數(shù)組的末尾向前遍歷,直到有子視圖的hitTest:withEvent:方法返回非空對(duì)象或者全部子視圖遍歷完畢
  • 若第一次有子視圖的hitTest:withEvent:方法返回非空對(duì)象,則當(dāng)前視圖的hitTest:withEvent:方法就返回此對(duì)象,處理結(jié)束

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

  • 最終,這個(gè)觸摸事件交給主窗口的hitTest:withEvent:方法返回的視圖對(duì)象去處理

注意:hitTest:withEvent:方法會(huì)忽略以下視圖:

不接受觸摸的三種情況.png
最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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