【问题标题】:How can I detect touch events on a UIImageView inside a deep hierarchy of UIViews?如何在 UIView 的深层层次结构中检测 UIImageView 上的触摸事件?
【发布时间】:2010-03-30 15:18:07
【问题描述】:

我正在 iPhone 上开发一个简单的游戏,我从一个基于 View 的应用程序开始,通过UIViewController 我正在加载一个自定义的UIView,其中包含更多的UIViews 和一些UIImageViews。我想检测一些UIImageViews 上的触摸事件,但到目前为止我还不能。

我为测试目的创建了第二个项目,并认为UIImageViews 在层次结构如下时处理触摸事件:

UIViewController -> UIView -> UIImageView,

但是当它是这样的时候:

UIViewController -> UIView -> UIView -> UIImageView

它们未被检测到。

注意事项:
- userInteractionEnabled 在所有情况下都是 YES
- 我上面提到的所有UIViewsUIImageViews 都是自定义子类。

您能想出什么原因,当自定义UIImageView 在视图层次结构中变得更深时无法接收触摸事件?

【问题讨论】:

    标签: iphone objective-c uiimageview touch


    【解决方案1】:

    触摸需要经过漫长而迂回的路线才能到达目的地。正式地,它们沿着响应者链向上,从第一个响应者开始,然后从最深的包含触摸的视图到其视图控制器,再到下一个包含触摸的视图,等等。

    但实际情况更加复杂,因为在寻找包含最深触摸的视图时,触摸本质上是通过调用hitTest:withEvent: 方法“询问”该信息的*别视图。这允许一些超级视图劫持触摸,这可能非常有用,例如 UIScrollView,它有时会在其子视图知道发生了什么之前执行操作(滚动/缩放)。

    这里有一些提示可以帮助确定视图可能无法响应触摸的原因:

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

    而且,您已经知道这一点,但请注意 userInteractionEnabled 标志!

    希望这足以隔离问题。

    【讨论】:

    • 首先感谢您的快速回复!我只是有时间检查你的提示。问题是我没有用initWithFrame 初始化 UIImageView。这是您的第二个提示,让我怀疑这是问题所在:“默认情况下,视图显示超出其框架大小,因此它们可能看起来不错,但在逻辑上比视觉上具有更小的尺寸 - 并且触摸响应基于逻辑(不是视觉)大小。”
    最近更新 更多