Objective c UIView hitTest:withEvent:呼叫有三个

Objective c UIView hitTest:withEvent:呼叫有三个,objective-c,cocoa-touch,ios,uiscrollview,Objective C,Cocoa Touch,Ios,Uiscrollview,我有一个没有子视图的UIScrollView。当我拖动滚动视图时,它的hitTest:withEvent:会被调用三次,并且在事件中不会有任何接触。为什么会这样(我看到另一篇帖子,但似乎没有结论)?这是滚动视图的hitTest…和pointInside:withEvent: 2011-05-11 20:12:37.472 MyApp[10909:707] hit test for UIScrollView 119.500000,102.000000, timestamp: 357978 touc

我有一个没有子视图的
UIScrollView
。当我拖动滚动视图时,它的
hitTest:withEvent:
会被调用三次,并且在事件中不会有任何接触。为什么会这样(我看到另一篇帖子,但似乎没有结论)?这是滚动视图的
hitTest…
pointInside:withEvent:

2011-05-11 20:12:37.472 MyApp[10909:707] hit test for UIScrollView 119.500000,102.000000, timestamp: 357978 touches: {()} 2011-05-11 20:12:37.475 MyApp[10909:707] pointInside for UIScrollView 119.500000,102.000000, timestamp: 357978 touches: {()} 2011-05-11 20:12:37.477 MyApp[10909:707] hit test for UIScrollView 119.500000,102.000000, timestamp: 357978 touches: {()} 2011-05-11 20:12:37.479 MyApp[10909:707] pointInside for UIScrollView 119.500000,102.000000, timestamp: 357978 touches: {()} 2011-05-11 20:12:37.481 MyApp[10909:707] hit test for UIScrollView 119.500000,102.000000, timestamp: 358021 touches: {()} 2011-05-11 20:12:37.482 MyApp[10909:707] pointInside for UIScrollView 119.500000,102.000000, timestamp: 358021 touches: {()} 2011-05-11 20:12:37.484 MyApp[10909:707] pointInside for UIScrollView 119.500000,396.000000, timestamp: 358021 touches: {()} 2011-05-11 20:12:37.472我的应用程序[10909:707]针对UIScrollView 119.500000102.000000的命中测试,时间戳:357978触摸:{()} 2011-05-11 20:12:37.475我的应用程序[10909:707]UIScrollView 119.500000102.000000的内部点,时间戳:357978接触:{()} 2011-05-11 20:12:37.477我的应用程序[10909:707]针对UIScrollView 119.500000102.000000的命中测试,时间戳:357978触摸:{()} 2011-05-11 20:12:37.479我的应用程序[10909:707]UIScrollView 119.500000102.000000的内部点,时间戳:357978接触:{()} 2011-05-11 20:12:37.481我的应用程序[10909:707]针对UIScrollView 119.500000102.000000的命中测试,时间戳:358021触摸:{()} 2011-05-11 20:12:37.482我的应用程序[10909:707]指向UIScrollView 119.500000102.000000的内部点,时间戳:358021触摸:{()} 2011-05-11 20:12:37.484我的应用程序[10909:707]指向UIScrollView 119.500000396.000000的内部点,时间戳:358021触摸:{()}
我不知道确切的原因,但以下是对这个问题的进一步见解:

  • 它似乎并不特定于UIScrollView。我用UIView运行了一个测试-结果相同
  • 无论视图层次结构或返回值如何,它似乎在根视图上被调用了三次
  • 对于前两个调用,传递给hitTest的事件基本上为空(但该点始终有效);事件具有有效的时间戳,但没有第三次呼叫的触摸信息
  • 看起来,
    UIResponder
    方法直到所有三个hitTest调用完成后才被调用。例如,touchesBegind:withEvent:直到结束才会被调用
  • 基于堆栈跟踪,所有三个调用都来自(我相信是封闭源代码)函数UIApplicationHandleEvent中的不同点
我的最佳猜测是,在某些情况下,
hitTest
的返回值可能会在调用之间发生变化。不过,我想不出为什么会发生这种情况。如果这不是真的,那么多次调用它是没有意义的


另一个想法是代码编写效率低下。这似乎不太可能,但根据这些信息,这是一种可能性。

我也有同样的问题,但实际上没有找到答案,但您可以使用以下两种解决方案之一:

一,。 将命中测试存储在一个数组中并进行比较,以便在相同的情况下返回,以防止连续调用3次

二,。 使用touchsbegind、touchscancelled、touchsended和touchsmove代替hittest,如下所示:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch * touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:touch.view];
    NSLog(@"%f - %f", touchLocation.x, touchLocation.y);
}

我使用了touchsbegind等解决方案,它的工作原理就像一个符咒:)

hitTest:
是一种实用方法,用于在特定点查找视图。它不代表用户点击触摸屏。hitTest被多次调用以响应同一事件是完全合理的;该方法所要做的就是返回点下的视图,不应触发任何副作用


如果您想跟踪触摸事件,应该覆盖
touchesbreated:
和friends。

我自己在自定义UIView子类中发现了完全相同的内容。我已经重写了hitTest:withEvent:method来进行一些定制处理,并认为多个调用都是由于一些错误代码造成的,但在这里阅读它似乎是iOS事件处理的一个怪癖。我很想知道为什么需要三个调用。不确定这是否是一个答案,所以我将在这里发布…假设您的继承人是:UIWindow-->UIViewController的UIView-->UIScrollView,是否可能对层次结构中的每个“可命中”视图进行命中测试?文档说明pointInside在层次结构中被调用。在滚动视图下添加UIView,查看是否调用了4次。另一个想法是它给你3,这样你就可以取平均值。我设置了一个项目,在VC的视图中有一个滚动视图,并对ViewDidDisplay中的一个随机点进行了命中测试。我只接到一个电话。你在哪里调用hitTest?还尝试拦截UIWindow上的事件并删除/断开响应程序链等。我仍然感到困惑!:)