iphone/ipad - 父 UIView 阻止触摸到达子视图 - 为什么?

发布于 2024-09-18 03:38:16 字数 583 浏览 7 评论 0原文

我有一个 UIView,它有很多子视图。子视图应该能够接收触摸事件,但由于某种原因,父 UIView 接受触摸并且不传递它。我以非常标准的方式创建了它,就像我总是创建视图一样:

UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,1024,768)];
    self.mainView = myView;
    [myView release];

    [self.view addSubview:self.mainView];

然后我创建子视图并正常添加它们:

[self.mainView addSubview:someOtherView];

我知道当我在主 UIWindow 中监听时 self.mainView 正在获取触摸事件:

VIEW: <UIView: 0x8d34aa0; frame = (0 0; 1024 768);

但是为什么我可以没有让子视图接收触摸?我不明白为什么有时会发生这种情况。我不会更改 mainView 的任何默认属性。

I have a UIView which has a bunch of subviews. The subviews should be able to receive touch events, but for some reason the parent UIView takes the touch and does not pass it on. I have created it in a very standard way like I always create views:

UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,1024,768)];
    self.mainView = myView;
    [myView release];

    [self.view addSubview:self.mainView];

Then I create subviews and add them as normal:

[self.mainView addSubview:someOtherView];

I know self.mainView is getting the touch events when I listen in the main UIWindow:

VIEW: <UIView: 0x8d34aa0; frame = (0 0; 1024 768);

But why in the world can I not get the subviews to receive touches? I don't understand why this happens sometimes. I am not changing any default properties of mainView.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

墨洒年华 2024-09-25 03:38:16

与父视图的框架有关。如果框架没有包含子视图,它们将不会收到触摸。

Had to do with the frame of the parent view. If the frame doesn't enclose the subviews they won't receive touches.

生生漫 2024-09-25 03:38:16

如果 UIView 触摸位于解决方案提到的超级视图的边界之外,则它们不会传递到子视图。

但是,如果您希望这些子视图响应触摸,请覆盖超级视图的 hitTest:withEvent:

事件交付文档

触摸事件。窗口对象使用命中测试和响应者链来查找接收触摸事件的视图。在命中测试中,窗口在视图层次结构的最顶层视图上调用 hitTest:withEvent: ;此方法通过在视图层次结构中返回 YES 的每个视图上递归调用 pointInside:withEvent: 来继续,沿着层次结构向下进行,直到找到发生触摸的子视图。该视图成为命中测试视图。

  1. 创建 UIView 的子类(或其他 UIView 子类)。
  2. 覆盖 hitTest:withEvent。
  3. 使用这个UIView子类作为父视图,这样子视图就可以响应触摸。

在子类中添加以下方法:

(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    NSEnumerator *reverseE = [self.subviews reverseObjectEnumerator];
    UIView *iSubView;

    while ((iSubView = [reverseE nextObject])) {

        UIView *viewWasHit = [iSubView hitTest:[self convertPoint:point toView:iSubView] withEvent:event];
        if(viewWasHit) {
            return viewWasHit;
        }

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

注意: 使用反向枚举器,因为子视图是从后到前排序的,并且我们要首先测试最前面的视图。

UIView touches do not get passed to subviews if they lie outside of the superview's bounds as mentioned by the solution.

However if you want these subviews to respond to touch, override hitTest:withEvent: of the superview.

Documentation on Event Delivery

Touch events. The window object uses hit-testing and the responder chain to find the view to receive the touch event. In hit-testing, a window calls hitTest:withEvent: on the top-most view of the view hierarchy; this method proceeds by recursively calling pointInside:withEvent: on each view in the view hierarchy that returns YES, proceeding down the hierarchy until it finds the subview within whose bounds the touch took place. That view becomes the hit-test view.

  1. Create a subclass of UIView (or other UIView subclass).
  2. Override hitTest:withEvent.
  3. Use this UIView subclass as the superview, so subview can respond to touches.

Add method below in subclass:

(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    NSEnumerator *reverseE = [self.subviews reverseObjectEnumerator];
    UIView *iSubView;

    while ((iSubView = [reverseE nextObject])) {

        UIView *viewWasHit = [iSubView hitTest:[self convertPoint:point toView:iSubView] withEvent:event];
        if(viewWasHit) {
            return viewWasHit;
        }

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

Note: Reverse enumerator used since subviews are ordered from back to front and we want to test the front most view first.

病女 2024-09-25 03:38:16

您是否触摸处理程序调用超类处理程序?

例如在你的 TouchesBegan 中,调用:

[super touchesBegan:touches withEvent:event];

Does you touch handlers call the superclass handlers?

e.g. in your touchesBegan, calling:

[super touchesBegan:touches withEvent:event];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文