iOS事件响应者链,为什么“响应了两次”?

在一个自定义UIView重写了hitTest和pointInside方法,并都调用了自己的父类方法。
然后写了一个demo,观察事件传递的流向。
最终效果如下图:

clipboard.png

下面是关键代码部分:

CGFloat width = screenWidth*0.6;

CGFloat height = 200;
CGFloat margin = 5;

CGFloat heightSub = height*0.4;

pragma mark - ViewA

_viewA = [[MyEventView alloc] init];
_viewA.name = @"蓝色View";
_viewA.backgroundColor = [UIColor blueColor];
[self.view addSubview:_viewA];
[_viewA mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(self.mas_topLayoutGuide).offset(margin);//iOS7之后才支持
    make.left.mas_equalTo(margin);
    make.width.mas_equalTo(width);
    make.height.mas_equalTo(height);
}];

_viewA1 = [[MyEventView alloc] init];
_viewA1.name = @"绿色View1";
_viewA1.backgroundColor = [UIColor greenColor];
[_viewA addSubview:_viewA1];
[_viewA1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(margin);
    make.left.mas_equalTo(margin);
    make.right.mas_equalTo(-margin);
    make.height.mas_equalTo(heightSub);
}];

UILabel *lab1 = [[UILabel alloc] init];
lab1.text = @"最下层视图";
lab1.textColor = [UIColor whiteColor];
[_viewA addSubview:lab1];
[lab1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.mas_equalTo(0);
}];

_viewA2 = [[MyEventView alloc] init];
_viewA2.name = @"绿色View2";
_viewA2.backgroundColor = [UIColor greenColor];
[_viewA addSubview:_viewA2];
[_viewA2 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.bottom.mas_equalTo(-margin);
    make.left.mas_equalTo(margin);
    make.right.mas_equalTo(-margin);
    make.height.mas_equalTo(heightSub);
}];

pragma mark - ViewB

_viewB = [[MyEventView alloc] init];
_viewB.name = @"灰色View";
_viewB.alpha = 0.6;
_viewB.backgroundColor = [UIColor grayColor];
[self.view addSubview:_viewB];
[_viewB mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(self.viewA.mas_bottom).offset(-90);
    make.right.mas_equalTo(-margin);
    make.width.mas_equalTo(width);
    make.height.mas_equalTo(height);
}];

_viewB1 = [[MyEventView alloc] init];
_viewB1.name = @"黄色View1";
_viewB1.backgroundColor = [UIColor yellowColor];
[_viewB addSubview:_viewB1];
[_viewB1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(margin);
    make.left.mas_equalTo(margin);
    make.right.mas_equalTo(-margin);
    make.height.mas_equalTo(heightSub);
}];

UILabel *lab2 = [[UILabel alloc] init];
lab2.text = @"中间层视图";
lab2.textColor = [UIColor whiteColor];
[_viewB addSubview:lab2];
[lab2 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.mas_equalTo(0);
}];

_viewB2 = [[MyEventView alloc] init];
_viewB2.name = @"黄色View2";
_viewB2.backgroundColor = [UIColor yellowColor];
[_viewB addSubview:_viewB2];
[_viewB2 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.bottom.mas_equalTo(-margin);
    make.left.mas_equalTo(margin);
    make.right.mas_equalTo(-margin);
    make.height.mas_equalTo(heightSub);
}];

pragma mark - ViewC

_viewC = [[MyEventView alloc] init];
_viewC.name = @"黑色View";
_viewC.backgroundColor = [UIColor blackColor];
[self.view addSubview:_viewC];
[_viewC mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(self.viewB.mas_bottom).offset(margin);
    make.centerX.mas_equalTo(0);
    make.width.mas_equalTo(width);
    make.height.mas_equalTo(height);
}];

_viewC1 = [[MyEventView alloc] init];
_viewC1.name = @"红色View1";
_viewC1.backgroundColor = [UIColor redColor];
[_viewC addSubview:_viewC1];
[_viewC1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(margin);
    make.left.mas_equalTo(margin);
    make.right.mas_equalTo(-margin);
    make.height.mas_equalTo(heightSub);
}];

UILabel *lab3 = [[UILabel alloc] init];
lab3.text = @"最上层视图";
lab3.textColor = [UIColor whiteColor];
[_viewC addSubview:lab3];
[lab3 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.mas_equalTo(0);
}];

_viewC2 = [[MyEventView alloc] init];
_viewC2.name = @"红色View2";
_viewC2.backgroundColor = [UIColor redColor];
[_viewC addSubview:_viewC2];
[_viewC2 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.bottom.mas_equalTo(-margin);
    make.left.mas_equalTo(margin);
    make.right.mas_equalTo(-margin);
    make.height.mas_equalTo(heightSub);
}];
阅读 4.5k
2 个回答

这个问题看来是要凉凉了 最近都没时间梳理。。。。

新手上路,请多包涵

系统对点有一个微调操作
apple工程师对这个问题的回复:
Yes, it’s normal. The system may tweak the point being hit tested between the calls. Since hitTest should be a pure function with no side-effects, this should be fine.
Luke

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进