今天講一下hitTest這個(gè)方法。
我們先看一張圖:
當(dāng)用戶點(diǎn)擊屏幕后端壳,UIApplication先響應(yīng)事件菠齿,然后傳遞給UIWindow惭每。如果UIWindow可以響應(yīng),就開始遍歷window的subviews围段。遍歷的過程中誊涯,如果第一個(gè)view1可以響應(yīng),那就遍歷view1的子視圖(subviews)蒜撮。如果view1不響應(yīng)暴构,就繼續(xù)往下找view2,以此類推。
我們來看兩個(gè)方法:
為了方便段磨,我們將兩個(gè)方法簡稱為A和B
方法A: - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
方法B: - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
對View進(jìn)行重寫這個(gè)兩個(gè)方法后取逾,就會(huì)發(fā)現(xiàn)點(diǎn)擊屏幕后,首先響應(yīng)的是方法A苹支。
如果方法A中砾隅,我們沒有調(diào)用父類的這個(gè)方法,那就根據(jù)這個(gè)方法A的返回view债蜜,作為響應(yīng)事件的view晴埂。(當(dāng)然返回nil究反,就是這個(gè)view不響應(yīng))
如果方法A中,我們調(diào)用了父類的這個(gè)方法儒洛,也就是:[super hitTest:point withEvent:event];
精耐,這個(gè)時(shí)候系統(tǒng)就要調(diào)用方法B;通過這個(gè)方法的返回值琅锻,來判斷當(dāng)前這個(gè)view能不能響應(yīng)消息卦停。
如果方法B返回的是NO,那就不用再去遍歷它的子視圖恼蓬。方法A返回的view就是可以響應(yīng)事件的view惊完。
如果方法B返回的是YES,那就去遍歷它的子視圖处硬。(就是上圖我們描述的那樣小槐,找到合適的view返回,如果找不到荷辕,那就由方法A返回的view去響應(yīng)這個(gè)事件凿跳。)
因此總結(jié)下來:
// 返回一個(gè)view來響應(yīng)事件 (我們?nèi)绻幌胗绊懴到y(tǒng)的事件傳遞鏈,在這個(gè)方法內(nèi)桐腌,最好調(diào)用父類的這個(gè)方法)
- (nullableUIView *)hitTest:(CGPoint)point withEvent:(nullableUIEvent *)event拄显;
// 返回的值可以用來判斷是否繼續(xù)遍歷子視圖(返回的根據(jù)是觸摸的point是否在view的frame范圍內(nèi))
- (BOOL)pointInside:(CGPoint)point withEvent:(nullableUIEvent *)event;
本文轉(zhuǎn)載自:對UIView的hitTest: withEvent: 方法的理解