關於hitTest和UIResponder


今天仔細看了一下UIView和UIResponder的介紹,着重看了一下hitTest的介紹。

首先是官方的:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

1.我們都知道,一個屏幕事件由響應鏈一步步傳下去。這個函數返回的view就是可以讓你決定在這個point的事件,你用來接收事件的view。當然,如果這個point不在你的view的范圍,返回nil。

2.這個函數忽略userInteractionEnabled,hidden,alpha<0.01,也就是你一個view隱藏或什么了,還是可以作為接收者。

3.調用次序是從subview top到bottom,包括view本身。

 

到底有什么用呢?這里舉個例子:比如你的一個view,叫myMapView上面有一個系統MKMapView,但不想這個MKMapView允許滾動捏合等操作,所以設置它

userInteractionEnabled = NO,但是又想接收點擊事件,所以你重寫

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event ,這時會發現根本沒有調用,而是調用了touchesCancel,因為userInteractionEnabled = NO了,所以不能算正常完成touch事件。

這時你就可以重寫這個hitTest,如下:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

{

    ifCGRectContainsPoint(mkMapView.frame ,point))

    {

        return mkMapView;

    }

    return [super hitTest:point withEvent:event];

}

這樣,mkMapView仍然可以接收touchesEnded事件進行單擊處理。

 

最后補充一下UIResponder的事件順序,首先必須先調用hitTest判斷接收事件的view,如果hitTest返回的view不為空,則會把hitTest返回的view作為第一響應者,然后調用

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

如果有UIGestureRecognizer或者userInteractionEnabled這種優先級高的,就調用

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

否則,如果中間手指移動什么的,就調用

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;(移出當前view了,就不touchesEnded了,又touchesCancelled)

最后正常完成事件,就調用-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM