美文网首页
UITouchEvent事件分发机制

UITouchEvent事件分发机制

作者: Smicro | 来源:发表于2016-05-12 15:28 被阅读159次
    Smicro

    根据右边的图来简要说一下hitTest检测流程:

    view接收到hitTest消息会通过自己调用pointInSize:withEvent:来判断该点是不是在自己内部。下面以(Judge)来表示view通过该方法的判断结果。

    触点1--A(Judge = YES)--B(Judge = NO)、D(Judge = NO)、E(Judge = NO)、F(Judge = NO)--A

    触点2--A(Judge = YES)--B(Judge = YES)--C(Judge = YES)--C

    触点3--A(Judge = YES)--B(Judge = NO)      

                                              --E相对D在顶部,优先遍历E(Judge = YES)--E

    触点4--不在A内--nil

    归纳:

    hitTest:会首先在 application 的 keyWindow 上调用(UIWindow 也是 UIView 的子类),并且该方法的返回值将被用来处理事件。会先判断产生触摸的 point 是否发生在自己的 bounds 内,如果没有将返回 nil;如果 point 在自己的范围内,则会为自己的每个子视图调用 hitTest: 方法,只要有一个子视图通过这个方法返回一个 UIView 对象,那么整个方法就一层一层地往上返回;如果没有子视图返回 UIView 对象,则父视图将会把自己返回。

    补充:

    如果某个view的enabled或userInteractionEnable为NO或者alpha<0.01,那么该view的hitTest永远(pointInSize:withEvent:返回YES/NO)都会返回nil,这意味着它和它的子视图没有机会去接收和处理事件。

    在自定义控件时,我们经常要响应一个并非是矩形的区域,那么这时候,就可以通过重写View的pointInSize:withEvent:来限制响应区域了。

    默认的写法:

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

    return CGRectContainsPoint(self.bounds, point);

    }

    现在想将范围限定在一个圆形内:

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

    BOOL inside = [self.superview pointInside:point withEvent:event];

    if (inside) {

    CGFloat radius = self.frame.size.width / 2;

    CGFloat dx = point.x - radius;

    CGFloat dy = point.y - radius;

    CGFloat distace = sqrt(dx * dx + dy * dy);

    return distace < radius;

    }

    return inside;

    }

    附:

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

    if (self.alpha <= 0.01 || !self.userInteractionEnabled || self.hidden) {

    return nil;

    }

    BOOL inside = [self pointInside:point withEvent:event];

    UIView *hitView = nil;

    if (inside) {

    NSEnumerator *enumerator = [self.subviews reverseObjectEnumerator];

    for (UIView *subview in enumerator) {

    if (hitView) {

    break;

    }

    }

    if (!hitView) {

    hitView = self;

    }

    return hitView;

    } else {

    return nil;

    }

    }

    相关文章

      网友评论

          本文标题:UITouchEvent事件分发机制

          本文链接:https://www.haomeiwen.com/subject/ckkprttx.html