當(dāng)我們手指點(diǎn)擊屏幕時,iphone os會用點(diǎn)擊的信息和類型生成一個UIEvent對象放入應(yīng)用程序的事件隊列中。然后UIApplication單例對象從隊列中頂部取出,調(diào)用當(dāng)前窗口UIWindow對象的hitTest:withEvent:方法, 看看當(dāng)前點(diǎn)擊的點(diǎn)是不是在window內(nèi), 如果是則逆序遍歷(后加載的先遍歷,因?yàn)楹蠹虞d才最靠前front,這樣優(yōu)化了查找效率)subview的hitTest:withEvent:方法,如果其中一個subview的hitTest:withEvent:方法返回了接收事件UIView,那么就不會繼續(xù)傳遞給剩下的其他subview。
hitTest:withEvent:方法的內(nèi)部實(shí)現(xiàn)如下:

注:hitTest內(nèi)部主要是一個pointInside:withEvent:方法,該方法和hitTest一樣都是UIView的方法,通過該方法可以判斷point是否落在view的bound范圍內(nèi)
hitTest尋找響應(yīng)View的路徑:
UIApplication分發(fā)事件(sendEvent方法)->UIWindow->View(rootController的View)->Subview(有可能childViewController的view)->Subview->Subview........ 直到找到響應(yīng)view為止。
touch響應(yīng)方法:
當(dāng)通過hitTest找到響應(yīng)View之后,就會調(diào)用該View(繼承UIResponder)的下列方法

官方文檔里面解釋了這幾個方法,the default implementation of this method forwards the message up the responder chain. 意思就是這些方法的默認(rèn)實(shí)現(xiàn)是把touch事件通過響應(yīng)者鏈進(jìn)行傳遞

響應(yīng)者鏈:
view(之前通過hitTest找到的相應(yīng)view)->superView->...->UIViewController的view->UIViewController->ParentController的view->parentController->...->RootController的view->RootController->UIWindow->UIApplication->AppDelegate
那么一個UIResponder是如何將事件傳遞給響應(yīng)者鏈的下一個對象的呢,其實(shí)靠的是UIResponder的一個只讀屬性串聯(lián)起來的,如下圖

當(dāng)一個view被addSubview到superView時,view的next就指向superView, UIViewController的View的next指向viewController, 而UIViewController的next指向parentController的View,如果是rootViewController那么next指向UIWindow