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

时间:2012-06-02 21:37:06

标签: ios uiview uigesturerecognizer subview uitapgesturerecognizer

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

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

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

btw:UIPanGestureRecognizer工作正常。它没有表现出上述行为。

enter image description here

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

您需要自定义父视图并更改其处理触摸的方式。有关详细信息,请参阅this question

答案 2 :(得分:0)

我发现关于覆盖pointInside:withEvent:的答案缺少解释或实现的细节。在最初的问题中,当用户点击未标记的黑色区域/视图(我们将其称为view2)时,事件框架将仅针对主窗口向下view2(及其直接子视图)触发hitTest:withEvent: ,并且永远不会在view1上击中它,因为在pointInside:point中测试的点不在view1框架的范围内。为了让subview1注册手势,您应该覆盖view2的hitTest:withEvent实现,以包括对子视图的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)
        }