ios的事件处理时从硬件开始,由驱动传递给系统层面,再传递给应用程序本身(UIApplication),然后会根据响应链找到所谓的firstResponsder,如果它不 进行处理,然后就传递给响应链下一级响应者,直到回到UIApplication(如果响应链上没有响应),由UIApplication进行默认处理。 在代码可控区域内,ios的屏幕点击事件是从上到下(firstResponsder沿着响应联到window再到app本身)的,所以如果点击所在的点不在某个view的区域内,这个view就不会收到这个事件(即这个事件对这个view透 明),view如果是一个controller的属性view(就是说这个controller的view指针指向这个view),这个viewController也不会收到这个消息。在默认情况下,view监测到的消息,如果view本身和他的subviews 都没有处理就会返回给view对应的viewController进行处理。 如果想要监测一个view外面的消息,就需要保证这个消息不会被其他的响应链节点截获(通常如果事件被响应链window之上的节点截获,我们就认为这个节点应该处理这个事件,我们不应该对这个事件进行处理);然后在 window中截获这个消息,再进行相应的处理(一般是响应联逆向处理,或者直接交给你希望的节点进行处理)。 特别危险: 上面提到的hack方法,有可能造成消息的循环发送,所以一定要注意。 当需要截获消息的view不再显示在能处理事件的window的最上面的时候,一定要把截获消息的处理去掉!
UIKit 为应用程序提供了编程手段来简化事件处理或者完全关闭事件流。下面的列表总结了这些方法:
在一段时间内关闭触摸事件的递交。
开启多点触摸的递交。 缺省情况下,视图忽略多点触摸事件序列中除了第一次触摸以外的其它所有事件。如果你想这个视图处理多点触摸,你必须为这个视图开启这个能力。通过编程设置你的视图的multipleTouchEnabled
限制事件递交给单个视图。
限制事件递交给子视图。一个自定义UIView 类可以重写hitTest:withEvent: