3

`我有一个 UIImageView 作为子视图的视图。主视图上有一个点击 GestureRecognizer,它在 99% 的时间都可以工作。

每隔一段时间,手势识别器似乎就会失败,并且事件会被向上推送到下一个响应者。我在该顶视图的 hitTest 方法中添加了一个断点,并且命中测试方法在所有情况下都正确返回了最里面的 UIImageView,包括当事件到达错误位置时。

在什么情况下,视图可能是 hitTest 的结果,但没有将事件传递给它的手势识别器?当手势选择器没有被调用时,我已经从 hitTest 断点打印出这个调试代码:

(lldb) po u
$2 = 0x20854520 <UIImageView: 0x20854520; frame = (0 0; 61 62); opaque = NO; layer = <CALayer: 0x208e7670>>

(lldb) po [u superview]
$0 = 0x1fd225e0 <HotspotView: 0x1fd225e0; frame = (303 663; 61 62); gestureRecognizers = <NSArray: 0x2082b850>; layer = <CALayer: 0x1fd15af0>>

(lldb) po ((HotspotView *)u.superview).gestureRecognizers
$1 = 0x208bc940 <__NSArrayI 0x208bc940>(
    <UITapGestureRecognizer: 0x20828fa0; state = Possible; cancelsTouchesInView = NO; delaysTouchesEnded = NO; view = <HotspotView 0x1fd225e0>; target= <(action=handleSingleTap:, target=<HotspotView 0x1fd225e0>)>>
)

u是命中测试的结果(UIImageView)。u.superview是附加了手势识别器的容器视图。所以,在这里,我确认它u.superview有一个手势识别器。那么,它不应该接收那个事件吗?在什么情况下这个事件不会进入 singleTap 而是冒泡到下一个响应者?

编辑:我已经设法再次捕捉到这个问题(XCode 在几分钟后我上次崩溃了......)现在我发现触摸甚至让它一直进入 HotspotView。touchesBegan 正确地获得了触摸,即使它随后未能调用手势识别器。我已经记录了成功和不成功点击的触摸和触摸事件(就它们是否调用 GR 而言),它们看起来是相同的。

所以,现在我更加迷茫了。

1) 为命中测试返回正确的对象
2) 正确的对象接收它的 touchesBegan 调用
3) 对象有它的手势识别器
4) 然而,有时,那个手势识别器没有被调用(没有可靠性和非常难以再现) .

4

1 回答 1

1

我的猜测是,在手势识别器无法识别的情况下,手势不是合格的点击。例如,如果您不小心连续点击两次,或者按住太久,或者稍微滑动手指,手势识别器可能看起来不像是单击一次。

换句话说,请记住触摸不是手势。您正在做一些很好的日志记录来显示结构是什么,并且您已经证明最近的触摸是在 UIImageView 上,但这并不意味着手势识别器将其识别为点击。可能存在其他冲突的手势识别器,或者该手势可能看起来不像轻敲。

顺便说一句,你在这里做了一件非常奇怪的事情。HotspotView 的大小与 UIImageView 完全相同。所以它的唯一目的似乎是检测水龙头。但是你可以单独使用 UIImageView 来做到这一点。为什么不保持简单?设置userInteractionEnabledUIImageView 并将点击手势识别器附加到 UIImageView 本身。

于 2013-05-13T18:08:19.177 回答