- hitTest的作用:
當(dāng)在一個(gè)view上添加一個(gè)屏蔽罩刽射,但又不影響對(duì)下面view的操作织咧,也就是可以透過(guò)屏蔽罩對(duì)
下面的view進(jìn)行操作,這個(gè)函數(shù)就很好用了懦底。
- hitTest的用法:
將下面的函數(shù)添加到UIView的子類中唇牧,也就是屏蔽罩類中即可。
-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView == self)
{
return nil;
}
else
{
return hitView;
}
}
- UiView touch事件傳遞
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
}
這個(gè)函數(shù)的用處是判斷當(dāng)前的點(diǎn)擊或者觸摸事件的點(diǎn)是否在當(dāng)前的view中聚唐。
它被hitTest:withEvent:調(diào)用丐重,通過(guò)對(duì)每個(gè)子視圖調(diào)用pointInside:withEvent:決定最終哪個(gè)視圖來(lái)響應(yīng)此事件。
如果 PointInside:withEvent:返回YES杆查,然后子視圖的繼承樹就會(huì)被遍歷(遍歷順序中最先響應(yīng)的為:與用戶最接近的
那個(gè)視圖弥臼。 it starts from the top-level subview),即子視圖的子視圖繼續(xù)調(diào)用遞歸這個(gè)函數(shù)根灯,直到找到可以響應(yīng)
的子視圖(這個(gè)子視圖的hitTest:withEvent:會(huì)返回self,而不是nil)掺栅;否則烙肺,視圖的繼承樹就會(huì)被忽略。
當(dāng)我們需要重寫某個(gè)UIView的繼承類UIViewInherit的時(shí)候氧卧,如果需要重寫hitTest:withEvent:方法桃笙,就會(huì)出現(xiàn)是否
調(diào)用[super hitTest:withEvent:]方法的疑問(wèn)?究竟是否需要都是看具體需求沙绝,這里只是說(shuō)明調(diào)與不調(diào)的效果搏明。
如果不調(diào)用,那么重寫的方法hitTest:withEvent:只會(huì)調(diào)用重寫后的代碼闪檬,根據(jù)所重寫的代碼返回self或nil星著,如果返
回self那么你的這個(gè)UIViewInherit類會(huì)接受你的按鍵,然后調(diào)用touches系列方法粗悯;否則返回nil那么傳遞給UIViewInherit類的按鍵到此為止虚循,
它不接受它的父view給它的按鍵,即不會(huì)調(diào)用touches系列方法。這時(shí)横缔,PointInside:withEvent:幾乎沒(méi)有作用铺遂。
如果調(diào)用,那么[super hitTest:withEvent:]方法首先是根據(jù)PointInside:withEvent:的返回值決定是否遞歸調(diào)用所
有子View的hitTest:withEvent:方法茎刚。對(duì)于子View的hitTest:withEvent:方法調(diào)用也是一樣的過(guò)程襟锐,這樣一直遞
歸下去,直到最先找到的某個(gè)遞歸層次上的子View的hitTest:withEvent:方法返回非nil膛锭,這時(shí)候粮坞,調(diào)用即結(jié)束,
最終會(huì)調(diào)用這個(gè)子View的touches系列方法泉沾。
如果我們不想讓某個(gè)視圖響應(yīng)事件捞蚂,只需要重載 PointInside:withEvent:方法,讓此方法返回NO就行了跷究。不
過(guò)從這里姓迅,還是不能了解到hitTest:WithEvent的方法的用途。
hitTest:withEvent:調(diào)用過(guò)程
The implementation of hitTest:withEvent: in UIResponder does the following:
It calls pointInside:withEvent: of self
If the return is NO, hitTest:withEvent: returns nil. the end of the story.
If the return is YES, it sends hitTest:withEvent: messages to its subviews. it starts from the top-level subview, and continues to other views until a subview returns a non-nil object, or all subviews receive the message.
If a subview returns a non-nil object in the first time, the first hitTest:withEvent: returns that object. the end of the story.
If no subview returns a non-nil object, the first hitTest:withEvent: returns self
This process repeats recursively, so normally the leaf view of the view hierarchy is returned eventually.
However, you might override hitTest:withEvent to do something differently. In many cases, overriding pointInside:withEvent: is simpler and still provides enough options to tweak event handling in your application.