兄弟姐妹子视图不会在iPhone中接收到触摸

时间:2011-12-18 21:54:38

标签: iphone ios uiview touchesbegan uiresponder

我有一个视图(parent),其中包含两个子视图,一个位于另一个(topChild)的顶部(bottomChild)。

如果仅点按屏幕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];
}

MYViewUIView的子类,仅记录touchesBegan

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%d", self.tag);
    [super touchesBegan:touches withEvent:event];
}

结果:

enter image description here

触摸绿色区域会生成以下日志:

TouchTest[25062:f803] 1
TouchTest[25062:f803] 3

我的第一个想法是让parent将所有touchesSomething次电话传播给其子女,但(A)我怀疑可能有更简单的解决方案和( B)我不知道哪个孩子将事件发送给父母,并且将touchesSomething次消息两次发送到同一视图可能会导致恶作剧。

在询问问题后,我发现此post建议覆盖hitTest以更改接收触摸的视图。我将尝试这种方法并更新问题是否有效。

2 个答案:

答案 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;