5

我有一堆子视图,它们都有用户交互部分(儿童)和全屏。问题是,如果我触及堆栈顶部的非交互式部分,它不会将该触摸传播到堆栈的其余部分。我的设置:

视图A --view B(全屏容器,本身不交互但有交互子视图)----view B1(交互)----view B2(交互)--view C(与B相同)----视图C1(交互)----视图C2(交互)

B 和 C 都是全屏,但 B1/B2/C1/C2 只是屏幕的一小部分。

[a addSubview:b];
[a addSubview:c];

如果我触摸 C1/C2 之外的任何东西,我希望触摸事件然后检查它是否击中 B(B1/B2)内部的任何地方,但它只是返回到 A,然后返回到 A 的父级。是否有可能做到这一点?如果我在 C 上设置 userInteractionEnabled NO 而在 C1/C2 上设置 YES,它也不会得到任何对内部调用的调用,尽管在这种情况下,B 会按预期进行操作。

编辑:最终手动遍历视图堆栈以仅检查某些子视图而不是所有子视图:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    if (self != self.topCustomViewsContainer) {     
        for (UIView *v in self.createdSubviews) {
            CGPoint newPoint = point;
            newPoint.x -= v.frame.origin.x;
            newPoint.y -= v.frame.origin.y;
            UIView *hit = [v hitTest:newPoint withEvent:event];
            if (hit)
                return hit;
        }
        return nil;

    }

    return [super hitTest:point withEvent:event];
}
4

2 回答 2

8

一种可能性是覆盖

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

视图 B 中的方法。只有当 B 的子视图被命中时,才能使其返回。试试这样:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  UIView *hitView = [super hitTest:point withEvent:event];
  if (hitView == self) {
    return nil;
  } else {
    return hitView;
  }
}
于 2013-04-17T19:20:21.710 回答
0

事件将视图层次结构从子级传播到父级(如您所见)。所以我想到了两种可能性:

让 C 成为 B 的子节点。它们的大小相同,而 C 显然已经有了透明背景,所以将其添加到 B 并使用[viewB bringSubviewToFront:viewC]使其首先接收触摸。它没有捕获的任何东西都将传递给它下面的视图,然后传递给父 A。

或者:手动捕获触摸,并强制它们查看 B(C 的兄弟)。这涉及在您的视图控制器类中实现它

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [viewC touchesBegan:touches withEvent:event];
    // Note this could be in sibling B or in parent A, depending on which
    // has a reference to the 'viewC' object
}
于 2013-04-17T19:19:18.867 回答