iOS视图控制器容器 | 子视图控制器将触摸事件传递给父视图控制器

4
在iOS5中,我在应用程序中实现了UITouchGesture,并使用UIViewController来包含它。当我添加一个子视图控制器(全屏)时,触摸事件会传递到其父视图控制器。是否有任何解决方案?我使用MPFlipViewController,当用户在子视图控制器上移动手指时,可以看到页面在其下面翻转。为了澄清,我通过以下方式将我的视图控制器添加为一个子视图控制器:
[self addChildViewController:vc];
[vc willMoveToParentViewController:nil];
[self.container addSubview:vc.view];
[vc didMoveToParentViewController:self];

容器只是一个UIView,用于容纳子视图控制器的视图和其他UIView对象。谢谢。
4个回答

6
你理解错了。控制器的包含是一回事,但这只是标准的视图层次结构和响应链问题。所以触摸事件最初被发送到父级;具体来说,调用其视图的-(UIView *)hitTest:withEvent:方法。如果找到子视图,则返回该子视图。否则,它会返回自己的一个视图。可能会返回自身。
如果父控制器正在捕获触摸,则意味着它从未被发送到子视图。而不是先发送到子视图,然后再向上发送到父级。
如果你想让父级在触摸捕获方面做些不寻常的事情,那就使用自定义视图并实现自己的-hitTest:withEvent:方法。首先,这样做并记录输入以查看发生了什么。

我修改了我的问题,它不是标准的视图层次结构的内容,因为我将ViewController作为子ViewController添加进去,它仍然会将触摸事件传递给父级的UIView对象,而这个子ViewController又是从父级继承下来的 :)。 - theiOSDude
1
除非您手动将触摸传递到该方向,否则UIKit不会按照此方式工作。查找位于触摸下面的最本地视图的搜索是从最上层的视图向下进行的。因此是从父视图到子视图,而不是相反。控制器包含添加到正常视图管理中,它不会改变基本原理。您认为如何找到触摸下面的视图? - Tommy

1
MPFlipViewController.m中,您应该查看此方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    // don't recognize simultaneously with scroll view gestures in content area
    if ([[otherGestureRecognizer view] isKindOfClass:[UIScrollView class]])
        return NO;

    // Allow simultanoues pan & swipe recognizers
    return YES;
}

将其改为类似以下内容:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    // don't recognize simultaneously with scroll view gestures in content area
    if ([[otherGestureRecognizer view] isKindOfClass:[UIScrollView class]])
        return NO;

    if (otherGestureRecognizer == GestureRecognizerOfYourChildViewController)
        return NO;

    // Allow simultanoues pan & swipe recognizers
    return YES;
}

当然,GestureRecognizerOfYourChildViewController是您的子视图控制器的手势识别器。

编辑:由于OP没有在自己的子视图控制器上使用手势识别器,因此解决方案有所不同。但我还是把第一个版本留在这里,因为它可能对其他有类似问题的人有帮助。

我能想到的最好的解决方案是,在MPFlipViewController中显示子视图控制器时禁用gestureRecognizers,并在移除子视图控制器并且MPFlipViewController再次出现在顶部时再次启用它们。使用enabled属性进行操作。

手势识别器在您自己的视图控制器中使用的“触摸链”之外工作,这就是为什么会出现您的问题的原因。


谢谢,我稍微修改了我的问题,我在ChildViewController上没有使用手势识别器,用户只是在子视图中将手指放在屏幕上,而在父视图上的MPFlipViewController则会吸收触摸并移动“页面”。 - theiOSDude
我更新了答案。但是子视图控制器是否对其接收到的触摸做出反应? - johnyu

1
你应该为子视图控制器实现触摸处理。允许子视图捕获所有触摸事件,然后将它们丢弃,以便不传递给父视图。
另一个解决方案可能是将子视图控制器包装在UINavigationController中,这可能会让你免费获得所需的行为。
你可以发布父视图控制器中的UITouchGesture代码,这可能会有帮助。

1

在iOS 7发布之前是不可能的,我想知道是否有任何专家现在已经完成了此事。


那么在iOS7中我该怎么做才能停止它呢?谢谢。 - theiOSDude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接