通过触摸到下面的UIViews

我有一个UIView与4个button和另一个UIView在button视图的顶部。 最上面的视图包含一个带有UITapGestureRecognizerUIImageView

我试图创build的行为是,当用户点击UIImageView它在屏幕的右下angular变小,animation变大。 当它很大时,我希望底部视图上的button被禁用,当它很小并且在右下angular时,我希望将触摸传递给button,并使其正常工作。 我几乎在那里,但我不能得到的触摸通过button,除非我禁用顶视图的UserInteractions

我有这个在我的initWithFrame:顶视图:

 // Add a gesture recognizer to the image view UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)]; tapGestureRecognizer.cancelsTouchesInView = NO; [imageView addGestureRecognizer:tapGestureRecognizer]; [tapGestureRecognizer release]; 

而我这是我的imageTapped:方法:

 - (void) imageTapped:(UITapGestureRecognizer *) gestureRecognizer { // Toggle between expanding and contracting the image if (expanded) { [self contractAnimated:YES]; expanded = NO; gestureRecognizer.cancelsTouchesInView = NO; self.userInteractionEnabled = NO; self.exclusiveTouch = NO; } else { [self expandAnimated:YES]; expanded = YES; gestureRecognizer.cancelsTouchesInView = NO; self.userInteractionEnabled = YES; self.exclusiveTouch = YES; } } 

使用上面的代码,当图像很大时,button是不活动的,当我触摸图像时,它缩小,button变成活动的。 但是,小图像没有收到触摸,因此不会扩大。

如果我在这两种情况下设置了self.userInteractionEnabled = YES ,那么图片会在触摸时展开和收缩,但是button永远不会触摸,并且会像禁用一样操作。

触摸时是否有图像展开和收缩,但是下面的button是否只在图像处于收缩状态时才会接触到图像? 我在这里做了些什么愚蠢的事情,想念一些明显的东西?

我疯了试图让这个工作,所以任何帮助将不胜感激,

戴夫

更新:

为了进一步testing,我touchesCancelled:touchesBegan:touchesCancelled:方法,并在包含UIImageView的视图上调用它们的超级实现。 通过上面的代码, touchesCancelled:永远不会被调用,而touchesBegan:总是被调用。

所以看起来这个视图正在触及,他们只是没有传递到下面的视图。

UPDATE

这是因为响应者链的工作方式? 我的视图层次结构如下所示:

 VC - View1 -View2 -imageView1 (has tapGestureRecogniser) -imageView2 -View3 -button1 -button2 

我认为操作系统首先做一个hitTest,因为View2在前面所以应该得到所有的触摸,这些都不会传递到View3,除非View2的userInteractions设置为NO,在这种情况下,imageView1也被阻止接收触摸。 这是如何工作的,有没有办法让View2通过View3的触摸?

UIGestureRecognizer是我认为的一个红鲱鱼。 最后解决这个问题我重覆了一下pointInside:withEvent:我的UIView: pointInside:withEvent:方法UIView:

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { BOOL pointInside = NO; if (CGRectContainsPoint(imageView.frame, point) || expanded) pointInside = YES; return pointInside; } 

这会导致视图捕捉所有触摸如果您触摸imageView或其扩展标志设置。 如果它没有展开,那么只有在imageView上的时候才会捕获触摸。

通过返回NO,顶层VC的视图查询其视图层次结构的其余部分寻找一个命中。

StoryboardXIBselect您的View


在这里输入图像说明


更经常地使用Storyboard ,对于这样简单的调整来说非常棒!

或者在Swift 3中

 view.isUserInteractionEnabled = false 

查看UIGestureRecognizerDelegate协议 。 具体来说, gestureRecognizer:shouldReceiveTouch:

你会想让每个UIGestureRecognizer成为你的UIViewController一个属性,

 // .h @property (nonatomic, strong) UITapGestureRecognizer *lowerTap; // .m @synthesize lowerTap; // When you are adding the gesture recognizer to the image view self.lowerTap = tapGestureRecognizer 

确保你让你的UIViewController成为一个委托,

 [self.lowerTap setDelegate: self]; 

那么,你会有这样的事情,

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (expanded && gestureRecognizer == self.lowerTap) { return NO; } else { return YES; } } 

当然,这不是确切的代码。 但是这是你想要遵循的一般模式。

我有另一个解决scheme。 我有两个视图,我们称它们为重叠的CustomSubView ,它们都应该接受触摸。 所以我有一个视图控制器和一个自定义UIView类,让我们调用它在界面生成器中设置的ViewControllerView ,然后我添加了两个视图,应该接受触摸到该视图。

所以我通过覆盖hitTest拦截ViewControllerView的触摸:

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { return self; } 

然后我在ViewControllerView覆盖:

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; for (UIView *subview in [self.subviews reverseObjectEnumerator]) { if ([subview isKindOfClass:[CustomSubView class]]) { [subview touchesBegan:touches withEvent:event]; } } } 

做与touchesEnded touchesCancelled完全相同touchesEnded touchesCancelled