UITapGestureRecognizer 不响应父视图外的子视图区域

Posted

技术标签:

【中文标题】UITapGestureRecognizer 不响应父视图外的子视图区域【英文标题】:UITapGestureRecognizer does not respond to subview area outside parent view 【发布时间】:2012-06-02 21:37:05 【问题描述】:

我有一个名为 view1 的 UIView。 view1 有一个名为 subview 的子视图。我在子视图中添加了UITapGestureRecognizer,如下所示:

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
[subview addGestureRecognizer:recognizer];

如果我点击了 subview 和 view1 之间重叠的区域,那么将调用 handleTap 方法。但是,如果我在 view1 之外的子视图上点击了一个区域,那么 handleTap 永远不会被调用。这种行为对吗?如果没有,有什么建议我应该检查什么?

顺便说一句:UIPanGestureRecognizer 工作正常。它不表现出上述行为。

【问题讨论】:

【参考方案1】:

这是 UiView 的默认行为,子视图应该在父视图范围内。如果你想要一些不同的东西更好,你可以创建一个自定义的顶视图子类并覆盖(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

【讨论】:

FormSheet 中呈现的视图是否也是如此?【参考方案2】:

您需要自定义父视图并更改其处理触摸的方式。详情请见this question。

【讨论】:

【参考方案3】:

我发现有关覆盖 pointInside:withEvent: 的答案缺乏解释或实施的细节。在最初的问题中,当用户点击黑色的未标记区域/视图(我们将其称为 view2)时,事件框架只会触发 hitTest:withEvent: 主窗口向下穿过 view2(及其直接子视图) , 并且永远不会为 view1 命中它,因为在 pointInside:point 中测试的点超出了 view1 的框架范围。为了让 subview1 注册手势,您应该覆盖 view2 的 hitTest:withEvent 实现以包括对 subview 的 pointInside:point 的检查

//This presumes view2 has a reference to view1 (since they're nested in the example).
//In scenarios where you don't have access, you'd need to implement this
//in a higher level in the view hierachy

//In view2
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? 

        let ptRelativeToSubviewBounds = convert(point, to: view1.subview)
        if view1.subview.point(inside:ptRelativeToSubviewBounds, with:event)
            return view1.subview
        
        else
            return super.hitTest(point, with: event)
        

【讨论】:

以上是关于UITapGestureRecognizer 不响应父视图外的子视图区域的主要内容,如果未能解决你的问题,请参考以下文章

为啥 print("\0007") 不响?

耳机一边响一边不响

The Intent 加载时声音不响

5分钟外设学堂:耳机不响别慌,换个插头能救活!

51单片机 Proteus仿真有源蜂鸣器始终不响原因及解决方法

解决笔记本输出音频用手机耳机有轻微电流或有一个声道不响