UIView的-hitTest:withEvent:调用了三次?
我试图拦截整个应用程序内发生的任何活动(即触摸)。
换句话说,我试图收到主 UIView(包含其余控件)中发生的任何触摸事件的通知。 为此,我认为 UIView 的方法 -hitTest:withEvent: 是一个很好的解决方案。
但是,当我在调用 [super hitTest:... withEvent:...] 之前 NSLog 进入此重写方法时,我发现对于我所做的任何触摸,它都会被调用 3 次,并且我看不到收到的事件有任何差异每次被调用时。
以下是如何在我的应用程序的主视图中实现该方法:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSLog(@"hitTest:withEvent called :");
NSLog(@"Event: %@", event);
NSLog(@"Point: %@", NSStringFromCGPoint(point));
NSLog(@"Event Type: %d", event.type);
NSLog(@"Event SubType: %d", event.subtype);
NSLog(@"---");
return [super hitTest:point withEvent:event];
}
这是我在此视图中单次触摸的 NSLog:
2010-11-29 14:09:26.892 Application[68818:207] hitTest:withEvent called :
2010-11-29 14:09:26.892 Application[68818:207] Event: <UITouchesEvent: 0x5716d60> timestamp: 37935.2 touches: {(
)}
2010-11-29 14:09:26.892 Application[68818:207] Point: {173, 498}
2010-11-29 14:09:26.892 Application[68818:207] Event Type: 0
2010-11-29 14:09:26.892 Application[68818:207] Event SubType: 0
2010-11-29 14:09:26.893 Application[68818:207] ---
2010-11-29 14:09:26.893 Application[68818:207] hitTest:withEvent called :
2010-11-29 14:09:26.893 Application[68818:207] Event: <UITouchesEvent: 0x5716d60> timestamp: 37935.2 touches: {(
)}
2010-11-29 14:09:26.893 Application[68818:207] Point: {173, 498}
2010-11-29 14:09:26.893 Application[68818:207] Event Type: 0
2010-11-29 14:09:26.893 Application[68818:207] Event SubType: 0
2010-11-29 14:09:26.893 Application[68818:207] ---
2010-11-29 14:09:26.893 Application[68818:207] hitTest:withEvent called :
2010-11-29 14:09:26.894 Application[68818:207] Event: <UITouchesEvent: 0x5716d60> timestamp: 37944.9 touches: {(
)}
2010-11-29 14:09:26.894 Application[68818:207] Point: {173, 498}
2010-11-29 14:09:26.894 Application[68818:207] Event Type: 0
2010-11-29 14:09:26.894 Application[68818:207] Event SubType: 0
2010-11-29 14:09:26.894 Application[68818:207] ---
我如何在这三个通知之间做出任何区别,以便触发我只想执行的操作单次触摸一次?
提前致谢 !
I am trying to intercept any activity (i.e. touches) that happens inside my whole application.
In other words, I am trying to be notified of any touch event that happens within my main UIView, containing the rest of my controls.
To do so, I thought the UIView's method -hitTest:withEvent: was a good solution.
However, when I NSLog into this overriden method before calling [super hitTest:... withEvent:...], I see that it is called 3 times for any touch I make, and I cannot see any difference in the event I receive each time it is called.
Here is how is implemented the method in the main view of my application :
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSLog(@"hitTest:withEvent called :");
NSLog(@"Event: %@", event);
NSLog(@"Point: %@", NSStringFromCGPoint(point));
NSLog(@"Event Type: %d", event.type);
NSLog(@"Event SubType: %d", event.subtype);
NSLog(@"---");
return [super hitTest:point withEvent:event];
}
And here is what I NSLog for a single touch in this view :
2010-11-29 14:09:26.892 Application[68818:207] hitTest:withEvent called :
2010-11-29 14:09:26.892 Application[68818:207] Event: <UITouchesEvent: 0x5716d60> timestamp: 37935.2 touches: {(
)}
2010-11-29 14:09:26.892 Application[68818:207] Point: {173, 498}
2010-11-29 14:09:26.892 Application[68818:207] Event Type: 0
2010-11-29 14:09:26.892 Application[68818:207] Event SubType: 0
2010-11-29 14:09:26.893 Application[68818:207] ---
2010-11-29 14:09:26.893 Application[68818:207] hitTest:withEvent called :
2010-11-29 14:09:26.893 Application[68818:207] Event: <UITouchesEvent: 0x5716d60> timestamp: 37935.2 touches: {(
)}
2010-11-29 14:09:26.893 Application[68818:207] Point: {173, 498}
2010-11-29 14:09:26.893 Application[68818:207] Event Type: 0
2010-11-29 14:09:26.893 Application[68818:207] Event SubType: 0
2010-11-29 14:09:26.893 Application[68818:207] ---
2010-11-29 14:09:26.893 Application[68818:207] hitTest:withEvent called :
2010-11-29 14:09:26.894 Application[68818:207] Event: <UITouchesEvent: 0x5716d60> timestamp: 37944.9 touches: {(
)}
2010-11-29 14:09:26.894 Application[68818:207] Point: {173, 498}
2010-11-29 14:09:26.894 Application[68818:207] Event Type: 0
2010-11-29 14:09:26.894 Application[68818:207] Event SubType: 0
2010-11-29 14:09:26.894 Application[68818:207] ---
How could I make any difference between those three notifications in order to trigger the action I want to make only one time for a single touch ?
Thanks in advance !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
确实有 3 次调用 hitTest。目前尚不清楚原因,但我们可以通过事件的时间戳推测前两个调用与完成前一个手势有关 - 这些时间戳总是非常接近上一次触摸发生的时间,并且与上次触摸发生的时间有一定距离。当前时间。
这就是我确定要处理哪个 hitTest 的方法:
There are indeed 3 calls to hitTest. It is not clear why, but we can surmise by the timestamps on the event that the first two calls are to do with completing the previous gesture - those timestamps are always very close to whenever the previous touch happened, and will be some distance from the current time.
This is how I determine which hitTest to process:
如果这对您来说仍然是个问题。
我找到了有关该主题的几个示例和讨论,但正确的解决方案非常简单。
一般来说,hittest 在 UIView 或 UIScrollView 中被调用三次 - 这是遍历视图层次结构的结果。
一个非常简单且对我来说始终合适的解决方案是:
在您为我实现的视图中实现函数 hittest
- 所有三个函数调用始终具有相同的位置 - 因此只需将位置存储在本地类中。
在 .h 文件中:
在 .m 文件中
该解决方案在几个项目中对我来说效果很好。
If this is still a problem for you.
I found several examples and discussions about this topic but the proper solution is quite simple.
In general hittest is called three times within a UIView or a UIScrollView - this results of traversing the view-hierarchy.
A quite simple and for me always suitable solution is:
implement the function hittest in the view you implemented
for me - all three function calls have always the same position - so just store the location in your local class.
in the .h File:
in the .m File
This solution works for me in several projects quite well.
您收到的事件响应的数量取决于视图层次结构。
来自 UIView 类参考。
简而言之,如果您触摸的视图具有三个子视图,并且这些视图可见并且在其父视图和触摸区域的范围内,您将收到三个命中测试响应。
The number of event responses you receive depends on the view hierarchy.
From the UIView Class Reference.
In a nutshell, if the view you touch has three subviews, and those views are visible and within the bounds of their superview and touch region, you will receive three hit test responses.
这个问题已经被问了好几年了,但我想回答一下:
系统多次调用 hitTest 和 pointInside 来固定位置,每次调用堆栈都不同,请参考 苹果官方回复。
This question has been asked for years, but I want to answer it:
The system calls hitTest and pointInside several times to fix the position, and each time the call stack is different, please refer to the official reply from apple.