我有一个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];
我知道self.mainView在主UIWindow中收听触摸事件:
VIEW: <UIView: 0x8d34aa0; frame = (0 0; 1024 768);
但是为什么在世界上我不能让子视图接受接触?我不明白为什么有时会发生这种情况。我没有改变mainView的任何默认属性。
答案 0 :(得分:15)
必须处理父视图的框架。如果框架没有包含子视图,则他们将不会接收到触摸。
答案 1 :(得分:12)
UIView触摸不会传递给子视图,如果它们位于解决方案所提到的超视图范围之外。
但是,如果您希望这些子视图响应触摸,请覆盖超级视图的hitTest:withEvent:
。
Documentation on Event Delivery
触摸事件。窗口对象使用命中测试和响应者链来查找接收触摸事件的视图。在命中测试中,窗口在视图层次结构的最顶层视图上调用hitTest:withEvent:此方法通过在视图层次结构中返回YES的每个视图上递归调用pointInside:withEvent:继续执行,继续向下移动层次结构,直到找到触摸发生在其边界内的子视图。该视图成为热门测试视图。
在子类中添加以下方法:
(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];
}
注意:由于子视图是从后到前排序的,因此我们希望首先测试最前面的视图。
答案 2 :(得分:0)
你是否触摸处理程序调用超类处理程序?
e.g。在你的touchesBegan中,打电话:
[super touchesBegan:touches withEvent:event];