0

我有一个带有两个子视图的视图 ( ),一个在另一个 ( ) 的parent顶部 ( )。topChildbottomChild

如果我只点击屏幕topChildparent接收触摸事件。

我应该改变什么来传播触摸事件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的子类在哪里。UIViewtouchesBegan

- (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传播给它的孩子,但是(A)我怀疑可能有一个更简单的解决方案,并且(B)我不知道哪个孩子将事件发送给父母,并且两次向同一个视图发送消息可能会引起恶作剧。touchesSomethingtouchesSomething

在提出问题后,我发现这篇文章建议覆盖hitTest以更改接收触摸的视图。如果可行,我将尝试这种方法并更新问题。

4

2 回答 2

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's 方法,具体取决于您在做什么,以及调用的位置可能在parentNotifiedTouchesBegan.

您当然可以知道哪个 subView 发送了事件,只需使用自定义方法通知 superview 而不是调用它的touchesBegan:. 使用self论据。

于 2011-12-18T22:06:38.457 回答
0

如果您不需要对孩子进行触摸,请设置

bottomChild.userInteractionEnabled = NO;
topChild.userInteractionEnabled = NO;
于 2011-12-20T17:33:26.157 回答