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

3
我正在iPhone上开发一个简单的游戏,我从一个基于View的应用程序开始,在UIViewController中加载了一个包含一些更多UIView和一些UIImageView的自定义UIView。 我想在一些UIImageView上检测触摸事件,但是迄今为止我还没有成功。
我创建了第二个项目进行测试,并发现当层次结构如下时,UIImageView会处理触摸事件:

UIViewController -> UIView -> UIImageView,

但是当它像这样:

UIViewController -> UIView -> UIView -> UIImageView

它们就不能被检测到。
注释: - 在所有情况下,userInteractionEnabled都是YES - 我提到的所有UIViewsUIImageViews都是自定义子类。
你能想到任何原因吗?为什么当自定义UIImageView越深入视图层次结构时无法接收触摸事件?
1个回答

4

触摸事件需要经过漫长而曲折的路径才能到达目的地。官方上来说,它们会沿着响应者链向上传递,从第一个响应者开始,然后从包含触摸点最深的视图到其视图控制器,再到下一个包含触摸点的视图等。

但实际情况更为复杂,因为在寻找包含触摸点最深的视图时,触摸点本质上是通过调用 hitTest:withEvent: 方法向最高级别的视图“询问”该信息。这使得一些父视图可以劫持触摸事件,这非常有用,例如在 UIScrollView 中,有时会在其子视图知晓情况之前执行一些操作(滚动/缩放)。

以下是一些提示,以帮助确定为什么某个视图可能无法响应触摸事件:

  • 覆盖每个视图上的[hitTest:withEvent:]1并在其被点击时使用NSLog,以查看哪些视图被考虑为响应者链。
  • 使用未记录的(因此在提交之前将其删除)UIView方法recursiveDescription在运行时检查所有视图的框架。视图默认情况下显示超出它们的框架大小,因此它们可能看起来很好,但逻辑上比视觉上小-而触摸是基于逻辑(而不是视觉)大小响应的。
  • 这可能听起来很蠢,但请仔细检查您的方法是否正确连接到您正在寻找的输出。例如,如果您期望当触摸UIButton时调用-[MyClass buttonPressed]方法,请仔细检查是否已将MyClass实例和@selector(buttonPressed)作为该按钮的目标/操作对添加。
  • 如果以上方法都不起作用,请覆盖touchesBegan:withEvent:并使用NSLog消息查看触摸事件沿着响应者链向哪里传递。

同时,你已经知道了,但要注意userInteractionEnabled标志!

希望这足以隔离问题。


2
首先感谢您的快速回复!我刚有时间检查了您的提示。问题在于我没有使用initWithFrame初始化UIImageView。正是您的第二个提示让我怀疑这是问题所在:“视图默认显示超出其框架大小,因此它们可能看起来很好,但在逻辑上比视觉上小 - 触摸基于逻辑(而不是视觉)大小响应。” - jester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接