- 如果在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ì)象或者全部子視圖遍歷完畢
- 首先調(diào)用當(dāng)前視圖的
若第一次有子視圖的
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
