我有一个视图(parent
),其中包含两个子视图,一个位于另一个(topChild
)的顶部(bottomChild
)。
如果仅点按屏幕topChild
,parent
会收到触摸事件。
我应该更改什么才能将触摸事件传播到bottomChild
?
代码:
- (void)viewDidLoad
{
[super viewDidLoad];
MYView* parent = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
parent.tag = 3;
parent.backgroundColor = [UIColor redColor];
MYView* bottomChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
bottomChild.tag = 2;
bottomChild.backgroundColor = [UIColor blueColor];
[parent addSubview:bottomChild];
MYView* topChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
topChild.tag = 1;
topChild.backgroundColor = [UIColor greenColor];
[parent addSubview:topChild];
[self.view addSubview:parent];
}
MYView
是UIView
的子类,仅记录touchesBegan
。
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"%d", self.tag);
[super touchesBegan:touches withEvent:event];
}
结果:
触摸绿色区域会生成以下日志:
TouchTest[25062:f803] 1
TouchTest[25062:f803] 3
我的第一个想法是让parent
将所有touchesSomething
次电话传播给其子女,但(A)我怀疑可能有更简单的解决方案和( B)我不知道哪个孩子将事件发送给父母,并且将touchesSomething
次消息两次发送到同一视图可能会导致恶作剧。
在询问问题后,我发现此post建议覆盖hitTest
以更改接收触摸的视图。我将尝试这种方法并更新问题是否有效。
答案 0 :(得分:1)
这是一个有趣的问题,可能是通过重新思考你的结构方式来解决的问题。但要使其按照您建议的方式工作,您需要在当前顶视图中捕获触摸事件,将其传递给父级,然后将其传播到父视图的所有子视图中。要使这项工作,您需要touchesBegan:
(或用于拦截触摸的任何其他方法)在所有视图中不执行任何操作,仅在父视图调用的方法中执行操作。
这是另一种说法,不处理视图中的触摸,捕获它们但通知父视图视图,然后根据需要调用子视图方法以产生所需的效果。
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Do nothing, parent view calls my parentNotifiedTouchesBegan method
[self.superview touchesBegan:touches withEvent:event];
}
- (void) parentNotifiedTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Act on the touch here just as my sibling views are doing
}
注意我在该代码中将super
更改为self.superview
。您可能也可能不想调用super
的方法,具体取决于您正在进行的操作以及可能位于parentNotifiedTouchesBegan
中的地方。
您当然可以知道哪个子视图发送了该事件,只需使用自定义方法通知superview而不是调用其touchesBegan:
。使用self
参数。
答案 1 :(得分:0)
如果您不需要接触孩子,请设置
bottomChild.userInteractionEnabled = NO;
topChild.userInteractionEnabled = NO;