如何调试谁在UIKit吃我的触摸?

bug*_*oaf 25 ios

我无法弄清楚为什么在我的视图中点击文本字段和按钮不起作用.我检查了所有明显的事情,例如userInteractionEnabled是否设置为YES,是否安装了手势识别器,以及前景中是否有不可见的视图.

在iOS中是否有最佳实践用于跟踪从第一次出现到消费时的触摸?

更新:

这两个答案都有帮助.在我的调查过程中,我了解到如果子视图超出其父级边界,即使父级没有剪切子视图,子视图也不会接收事件.我从文本字段中打印出了没有触及的超视图链,我看到其中一个视图的高度为0.我设置了一些约束来拉伸它,我的问题就解决了.

Bry*_*hen 21

您可以子类化UIWindow和覆盖-[UIWindow sendEvent]:,然后在调用它时,用于-[UIWindow hitTest:withEvent:]测试哪个视图将接收事件.

然后,您可以调用-[UIView recursiveDescription]打印一些调试信息,以帮助您了解该视图接收触摸事件的原因.

记得[super sendEvent:]在你完成后打电话.


对于那些使用Storyboard并想知道如何更改主应用程序窗口类的人:

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow? = TestWindow()
    // ....
}
Run Code Online (Sandbox Code Playgroud)

只需提供AppDelegate's windowvar 的默认值.当应用程序启动时,UIApplicationMain将实例化一个委托并要求它window.如果windownil它会自动创建一个新的.但是如果我们在这里提供默认值,它将在整个应用程序中使用.


Ham*_*mza 9

您可以使用符号断点进行调试:

-[UIWindow sendEvent:]po $arg3

在此处输入图片说明 日志:

<UITouchesEvent: 0x6000026fa6d0> timestamp: 179462 touches: {(
<UITouch: 0x7f84d6f10380> phase: Began tap count: 1 force: 0.000 
window: <UIWindow: 0x7f84d6d0ad10; frame = (0 0; 375 812); autoresize = W+H; 
gestureRecognizers = <NSArray: 0x600001aa8870>; layer = <UIWindowLayer: 0x6000014bd7e0>> view: <UIView: 0x7f84d6d0bff0; frame = (0 0; 375 812); 
autoresize = W+H; layer = <CALayer: 0x6000014bdc60>> location in window: {165.66665649414062, 232.33332824707031} previous location in window: 
{165.66665649414062, 232.33332824707031} location in view: {165.66665649414062, 
232.33332824707031} previous location in view: {165.66665649414062,232.33332824707031}
)}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案。如果您只想要日志而不是停止调试器的断点,我还建议检查“评估操作后自动继续” (2认同)

Gui*_*ent 6

这不是问题的直接答案,但是导致触摸消失的一个很常见的原因是控件位于uiview中,该控件的尺寸小于该控件的大小,但是没有限制其范围,因此您不会看到父控件视图较小(甚至可能为零)。

Parent UIView size=0x0, clipToBounds=false

   Child UIButton size=100x50
Run Code Online (Sandbox Code Playgroud)

=>子按钮不会收到任何触摸事件。