关于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。

 

 

posted on 2013-06-12 23:50  VicStudio  阅读(2788)  评论(1编辑  收藏  举报