我如何知道屏幕上的任何对象何时被点击?

How can I know when any of the objects on screen were tapped?

首先,我不是在问如何添加手势识别器或如何创建按钮。我想要的是在不干扰相关屏幕元素的情况下知道"somebody touched the screen in any way"。

关键是我有用户可以点击的元素(太棒了,不是吗?)。然后我有一个覆盖在所有内容之上的视图 (window addSubview)。此视图显示有一些延迟,我希望应用程序表现得好像此视图不存在,直到其 "show" 动画开始。然后,如果用户点击任何提到的元素,这些元素不是也不可能都是覆盖视图的父视图,元素应该像往常一样高亮和触发,而要覆盖的视图应该取消它的显示动画(alpha 0-> 1) 并从层次结构中删除自身。

tl;dr: 我如何监听屏幕上任何对象的任何事件,而不必为 "watch" 每个对象编写显式代码 —我只想知道一个手势发生了,而不是在哪里,不是如何,不是什么?而且我不想弄乱作为事件接收者的视图。这可能吗?

你只需要继承你的主window,你会在那里找到所有的触摸事件。 UIWindow 中有一个方便的包罗万象的方法,称为 sendEvent:,它可以查看事件处理管道开始附近的每个事件。如果你想做任何非标准的附加事件处理,这是放置它的好地方。像这样:

- (void)sendEvent:(UIEvent *)event {
  if ([self eventIsNoteworthy:event]) [self extraEventHandling:event];
  [super sendEvent:event];  // Apple says you must always call this!
}

文档:UIWindow class reference | iOS event delivery docs

This blog post 还提到了如何覆盖 hitTest:withEvent: 以在事件绑定到视图层次结构中的目标叶子视图之前捕获一些事件。如果需要,您还可以在 UIWindow 对象上覆盖该方法。

Note : You will not get keyboard touch events through this solution.

在叠加视图中,按如下方式覆盖 hitTest:

override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
    let result = super.hitTest(point, withEvent:event)
    if result === self {
        println("tapped the view")
        return nil
    }
    return result
}

结果是,如果覆盖视图被点击,它会响应(如 "tapped the view" 输出到控制台所证明的那样)但它允许点击落到它后面的任何东西(因为它 returns nil)。这实际上是一个不可触摸的视图,但它知道何时被触摸。