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

时间:2022-10-30 12:06:09

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 UIViews and some UIImageViews. I want to detect touch events on some of the UIImageViews, but I wasn't able so far.

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

I've created a second project for testing purposes and figured that UIImageViews handle touch events when the hierarchy is like :

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

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
- all UIViews and UIImageViews I mention above are custom subclasses.

注:- userInteractionEnabled在所有情况下都是YES -我上面提到的所有uiview和UIImageViews都是自定义子类。

Can you think of any reason why, when a custom UIImageView gets deeper in the view hierarchy can't receive touch events?

你能想到为什么,当一个自定义的UIImageView在视图层次结构中越深就不能接收触摸事件吗?

1 个解决方案

#1


4  

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. 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.

但真正的情况更加复杂,因为在寻找深度触控(包括视图)视图时,touch通过调用hitTest:withEvent: method来“询问”该信息的最高层次视图。这允许一些超视图劫持触摸,这是非常有用的,就像在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中,当它们被击中,以查看谁正在被考虑为responder chain。
  • Use the undocumented (and-therefore-take-it-out-before-you-submit) UIView method recursiveDescription to check the frames of all your views at runtime. 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时调用您的- [class mybuttonpressed]方法,请双击您已经为该按钮添加了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.
  • 如果这些都不起作用,可以用NSLog消息覆盖touchesBegan:withEvent:查看触摸在responder chain上的位置。

And, you already know this, but watch out for the userInteractionEnabled flag!

您已经知道这个,但是要注意userInteractionEnabled标志!

Hopefully that's enough to isolate the problem.

希望这足够把问题分离出来。

#1


4  

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. 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.

但真正的情况更加复杂,因为在寻找深度触控(包括视图)视图时,touch通过调用hitTest:withEvent: method来“询问”该信息的最高层次视图。这允许一些超视图劫持触摸,这是非常有用的,就像在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中,当它们被击中,以查看谁正在被考虑为responder chain。
  • Use the undocumented (and-therefore-take-it-out-before-you-submit) UIView method recursiveDescription to check the frames of all your views at runtime. 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时调用您的- [class mybuttonpressed]方法,请双击您已经为该按钮添加了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.
  • 如果这些都不起作用,可以用NSLog消息覆盖touchesBegan:withEvent:查看触摸在responder chain上的位置。

And, you already know this, but watch out for the userInteractionEnabled flag!

您已经知道这个,但是要注意userInteractionEnabled标志!

Hopefully that's enough to isolate the problem.

希望这足够把问题分离出来。