事件监听就要考虑几个点: 事件的传递,响应链 传递过程的主要方法
系统会找到第一响应者: 通过UIview及其子类查找 通过调用 视图的
The implementation of hitTest:withEvent: in UIResponder does the
following:It calls pointInside:withEvent: of self
If the return is NO, hitTest:withEvent: returns nil. the end of the story.
If the return is YES, it sends hitTest:withEvent: messages to its subviews. it starts from the top-level subview, and continues to other views until a subview returns a non-nil object, or all subviews receive the message.
If a subview returns a non-nil object in the first time, the first hitTest:withEvent: returns that object. the end of the story.
If no subview returns a non-nil object, the first hitTest:withEvent: returns self This process repeats recursively, so normally the leaf view of the view hierarchy is returned eventually.
However, you might override hitTest:withEvent to do something differently. In many cases, overriding pointInside:withEvent: is simpler and still provides enough options to tweak event handling in your application.
- 调用 自己的pointInside:withEvent:
- 如果 返回NO则 hitTesdt:withEvent:返回nil。结束这一层
- 如果返回是YES, 将发送hitTest:withEvent:消息到它(self)的subView,从顶层级子视图到其他视图,直到有一个视图返回一个非nil对象,不然所有的对象都会接收到这个信息。
- 如果一个子view第一次返回一个非空对象, 第一次调用hitTest:withEvent:返回那个对象。结束这一层。
- 如果所有子view返回的都是空对象,第一次的hitTest:withEvent: 返回它本身
下面借网络上一张图片展示如下:
事件传递可以跳过,某些层级,如果需要跳过,需要在hitTest中进行一些处理。
响应链:
事件传递
事件的完整处理过程:
- 先将事件对象由上往下传递(由父控件传递给子控件),找到最合适的控件来处理这个事件
- 调用最合适控件的touches..方法
- 如果调用了[super touches..];就会将事件顺着响应者【能处理事件的对象】链条往上传递,传递给上一个响应者
- 接着就会调用上一个响应者的touches..方法
谁是上一个响应者:
- 如果当前这个view是控制器的view,那么控制器就是上一个响应者
- 如果当前这个view不是控制器的view,那么父控件就是上一个响应者
点:
响应者对象:能处理事件的对象,继承了UIResponder
响应者链条:由多个响应者对象连接起来的链条
链条作用:当点击了某一个view时,view将事件处理完毕,可能会将事件传递给上一个响应者,而上一个又可以抛给更上一个响应者,这样就能形成一个链条,保证链条上的每一个对象都能处理这个事件。即能调用其touch..方法
能让多个控件处理同一个触摸事件
怎么往上传【谁是上一个响应者】:取决于是不是控制view
注意:
响应者链条是包含有控制器的,但事件的传递【仅为父控件传递给子控件】则是不包括有控制器