简体   繁体   English

如何在UIViews的深层次结构中检测UIImageView上的触摸事件?

[英]How can I detect touch events on a UIImageView inside a deep hierarchy of UIViews?

I am developing a simple game on iPhone and I started with a View based application, and through the UIViewController I am loading a custom UIView that contains some more UIView s and some UIImageView s. 我正在iPhone上开发一个简单的游戏,我开始使用基于View的应用程序,通过UIViewController我正在加载一个包含更多UIView和一些UIImageView的自定义UIView I want to detect touch events on some of the UIImageView s, but I wasn't able so far. 我想检测一些UIImageView上的触摸事件,但到目前为止我还没能。

I've created a second project for testing purposes and figured that UIImageView s handle touch events when the hierarchy is like : 我已经创建了第二个用于测试目的的项目,并且认为UIImageView在层次结构如下时处理触摸事件:

UIViewController -> UIView -> UIImageView , UIViewController - > UIView - > UIImageView

but when it's like : 但是当它像:

UIViewController -> UIView -> UIView -> UIImageView UIViewController - > UIView - > UIView - > UIImageView

they are not detected. 他们没有被发现。

Notes: 笔记:
- userInteractionEnabled is YES in all cases - userInteractionEnabled在所有情况下都为YES
- all UIViews and UIImageViews I mention above are custom subclasses. - 我上面提到的所有UIViewsUIImageViews都是自定义子类。

Can you think of any reason why, when a custom UIImageView gets deeper in the view hierarchy can't receive touch events? 您能想到任何原因,当自定义UIImageView在视图层次结构中变深时无法接收触摸事件吗?

Touches take a long and circuitous route to their destination. 接触需要一条漫长而迂回的路线才能到达目的地。 Officially, they go up the responder chain, which starts at the first responder, and then goes from the deepest-touch-including view to its view controller, to the next-up touch-including view, etc. 正式地,他们沿响应链上行,从第一响应者开始,然后从最深触摸视图到视图控制器,到下一个触摸 - 包括视图等。

But the real picture is even more complicated, since, in finding the deepest-touch-including view to go to, the touch essentially "asks" the highest-level view for that info by calling the hitTest:withEvent: method. 但实际情况更加复杂,因为在找到最深入的触摸视图时,触摸实际上是通过调用hitTest:withEvent:方法“询问”该信息的最高级别视图。 This allows some superviews to hijack touches, which can be very useful, as in UIScrollView , which sometimes does things (scrolls/zooms) before its subviews know what's going on. 这允许一些超级视图劫持触摸,这可能非常有用,如UIScrollView ,它有时会在其子视图知道发生了什么之前做事情(滚动/缩放)。

Here are a few tips to help determine why a view might not be responding to touches: 以下是一些提示,可帮助确定视图可能无法响应触摸的原因:

  • Override [hitTest:withEvent: ] 1 on each of your views and NSLog when they get hit to see who is being considered for the responder chain. 在每个视图和NSLog上覆盖[hitTest:withEvent: ] 1 ,当它们被击中时,看看谁正在考虑响应者链。
  • Use the undocumented (and-therefore-take-it-out-before-you-submit) UIView method recursiveDescription to check the frames of all your views at runtime. 使用未记录的(因此在提交之前采用它) UIView方法recursiveDescription来检查运行时所有视图的帧。 Views display beyond their frame sizes by default, so they may appear ok, but have smaller sizes logically than visually -- and the touches respond based on the logical (not visual) sizes. 默认情况下,视图显示超出其帧大小,因此它们可能看起来没问题,但逻辑上比视觉上更小 - 并且触摸响应基于逻辑(非可视)大小。
  • This may sound dumb, but double-check that your methods are correctly connected to the output you're looking for. 这可能听起来很愚蠢,但请仔细检查您的方法是否正确连接到您正在寻找的输出。 For example, if you're expecting your - [MyClass buttonPressed] method to get called when a UIButton is touched, double-check that you've added your MyClass instance and @selector(buttonPressed) as a target/action pair for that button. 例如,如果您希望在触摸UIButton时调用 - [MyClass buttonPressed]方法,请仔细检查您是否已将MyClass实例和@selector(buttonPressed)添加为该按钮的目标/操作对。
  • If none of those work, override touchesBegan:withEvent: with NSLog messages to see where the touches are going up the responder chain. 如果这些都不起作用,请覆盖touchesBegan:withEvent: with NSLog消息,以查看响应链上的触摸位置。

And, you already know this, but watch out for the userInteractionEnabled flag! 并且,您已经知道这一点,但请注意userInteractionEnabled标志!

Hopefully that's enough to isolate the problem. 希望这足以隔离问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM