【问题标题】:How do override hitTest to allow my subview to receive touch events?如何覆盖 hitTest 以允许我的子视图接收触摸事件?
【发布时间】:2014-08-12 03:55:57
【问题描述】:

我有一个包含另一个视图的 UIView,它自身包含一个 UIButton。问题是 MENUVIEW 真的很窄,所以我的 DROPDOWN 延伸到它上面,当它发生并且用户点击 (K) 时没有任何反应。我知道我必须覆盖 HitTest: 和 pointInside: 但我不确定在哪个视图中以及如何?

我是否覆盖 A、B 或 K 中的 hitTest?并且点在 A、B 或 K 内?

例子:

(A) is MENUVIEW, the parent of all views
(B) is DROPDOWN, a subview of MENUVIEW
(K) is UIBUTTON, a subview of DROPDOWN

图表:

    +---------------+
    |A              |         
    |               |               
    |               |         
    |               |         
    |+--------------|----------+
    ||B             |  +K---+  |
    ||              |  +----+  |
    |+--------------|----------+
    +---------------+

更新:

这是我放入的代码,但它不起作用。使用下面的代码,我单击 B,然后 B 将打开并显示 K,但 K 仍然不可单击。 Point inside 没有被调用 (A)?

    #pragma mark - Clickable Area()
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    {
        CGFloat radius = 200.0;
        CGRect frame = CGRectMake(self.dropDownMenu.frame.origin.x, self.dropDownMenu.frame.origin.y + 50,
                                  200,
                                  174); <-- this B's frame area minus the part of B inside A (i.e. just K and the part of B outside A)

        if (CGRectContainsPoint(frame, point)) {
            return self.dropDownMenu;
        } else {
            return [super hitTest:point withEvent:event];
        }
        return nil;
    }

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
    {
        if (CGRectContainsPoint(self.bounds, point)) {
            return YES;
        }
        return NO;
    }

    @end

【问题讨论】:

  • 请提供一些源代码。另外,这里有一些可能有用也可能没用的东西:检查userInteractionEnabled
  • 还有,你为什么要和 hitTest 和朋友们搞混?

标签: ios objective-c hittest


【解决方案1】:

你应该做一个足够大的父视图。并覆盖 d 的 pointInside 和 hittest 当点不在 a|b|c 区域时,返回 nil 让下面的视图响应事件。(返回 nil 表示 userinteractionenabled = NO)

- (UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
1.convert b's frame to the view D
if (point inside B's convertedFrame) {
    return B;
}
xxxxx {
    return A
}
XXXXX {
    return C;
}
return nil;
}

+-----------------------------+
+---------------+           D |
|A              |             |
|               |             |  
|               |             |
|               |             |
|+--------------|----------+  |
||B             |  +K---+  |  |
||              |  +----+  |  |
|+--------------|----------+  |
+---------------+             |
+-----------------------------+

如果b响应事件,那么k甚至可以响应不在a内部的k。

【讨论】:

  • 我不能让 (D) 或 (A) 更大。 (B) 必须适合 (A),它只有 60 像素宽,但 (B) 是 200 像素宽。想想下拉菜单或滑出菜单。
  • 没关系,可以覆盖A的hittest,返回子视图K或者b.hitTest:event。请记住,当不在区域 a|b|k 中时,返回 nil 让下视图响应
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多