关于点击测试(hitTest)的几点结论

来源:互联网 发布:幼儿园淘宝活动方案 编辑:程序博客网 时间:2024/06/05 10:15

点击测试遇到疑惑,重新结合文档再研究了一下

1、两个视图AA和BB,AA加在BB上,AA 的clipsTobounds设置为NO。


1、如果我们点击BB和AA的非叠加区域,测试结果是,只有BB是

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

       return inInside;

}

返回Yes,但是AA视图里面的方法就返回NO。

2、如果点击BB和AA的叠加区域,图中的黑色阴影部分

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

       return inInside;

}

这个方法在view BB和AA都返回YES

3、此外

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

   

}


- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

   

}

这两个方法,不论我们点击BB的哪里,这两个方法在AA中都不执行,在BB中都可能会执行。

4、我们在BB上加了一个tap手势,然后将BB和AA的属性userInteractionEnabled都设置为Yes,当我们点击BB的非叠加区域时,3的两个方法都执行,不走那个tap事件,tapAction。

5、同上,我们点击叠加区域,3的方法走第一个,第二个不走,然后tapAction这个方法会走。

6、如果我们在AA上面也加一个手势firstTapGesture,当我们点击叠加区域时,会走那个BB的手势方法secondTagAction,但是如果我们将BB的userInteractionEnabled设为NO(之前都是设置为Yes),那就会走firstTapGesture。

下面是detailed codes

- (void)viewDidLoad {

    [superviewDidLoad];

    AView *aView = [[AView allocinitWithFrame:CGRectMake(100,100,200,200)];

    aView.backgroundColor = [UIColororangeColor];

    aView.userInteractionEnabled =YES;

    UITapGestureRecognizer *firstTapGesture = [[UITapGestureRecognizer alloc]initWithTarget:selfaction:@selector(firstTapAction)];

    [aView addGestureRecognizer:firstTapGesture];

    [self.viewaddSubview:aView];

    

    BView *bView = [[BView alloc]initWithFrame:CGRectMake(75,75, 220,220)];

    bView.backgroundColor = [UIColor redColor];

    bView.userInteractionEnabled =YES;//这里在测试中可以设为NO

    UITapGestureRecognizer *tapGesture =            [[UITapGestureRecognizer alloc]initWithTarget:selfaction:@selector(secondTapAction)];

    [bView addGestureRecognizer:tapGesture];

    [aView addSubview:bView];

}

- (void)firstTapAction {

    NSLog(@"first tapAction start");

}

- (void)secondTapAction {

    NSLog(@"second  tapAction start");

}

下面的来自苹果官方文档:https://developer.apple.com/library/content/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html#//apple_ref/doc/uid/TP40009541-CH4-SW1

If the point passed into hitTest:withEvent: is not inside the bounds of the view, the first call to the pointInside:withEvent:method returns NO, the point is ignored, and hitTest:withEvent: returns nil

If a subview returns NO, that whole branch of the view hierarchy is ignored, because if the touch did not occur in that subview, it also did not occur in any of that subview’s subviews. This means that any point in a subview that is outside of its superview can’t receive touch events because the touch point has to be within the bounds of the superview and the subview. This can occur if the subview’s clipsToBounds property is set to NO.

翻译第二段:如果一个子视图的pointInside方法返回NO,那么那个视图层级的所有分支都将被忽视,因为如果那个touch没有发生在那个子视图,那么这个子视图的任何子视图也不会发生,这意味着,这意味着:一个出了他的父视图的子视图不可能收到任何touch 事件,因为touch的点必须在父视图和子视图的交叉里面。

(但实际是这样的,出现这种情况,那个pointInside:withEvent还能返回yes,但并不代表会发生touch events,两点:如果父视图都没有收到touch events 那么子视图肯定也没有,因为子视图在父视图的外面,点击子视图父视图肯定收不到touch event,由于父视图没有收到,那么可以推理子视图肯定也收不到touch事件

his can occur if the subview’s clipsToBounds property is set to NO.  



0 0
原创粉丝点击