关于事件传递的总结

发现自己把事件传递给弄混了,果然还是得总结和复习~~

UIEvent and UITouch

UITouch包含了如下四个phase

  • UITouchPhaseBegan
  • UITouchPhaseMoved
  • UITouchPhaseStationary
  • UITouchPhaseEnded
  • UITouchPhaseCancelled

为了处理UIEvent,我们需要重写如下方法

  • touchesBegan:withEvent:
  • touchesMoved:withEvent:
  • touchesEnded:withEvent:
  • touchesCancelled:withEvent:

UIEvent的传递

当一个TouchEvent 需要传送给某一个
view时(触碰事件的传递路径)

  • window将UIEvent转发给hit-test view
  • 如果hit-test view不能响应该事件,则沿着view的responder chain一直往上走直到找到一个能处理这个UIEvent的对象

关于hit-testing

就是找出用户触碰的view。

  • 根据触碰的点的坐标,找到包含该点的某个view a的bounds
  • 然后依次检查触碰的点是否落在a的subview中,直到找到包含触碰点的a的最小的后代view(the lowest view in the view hierarchy that contains the touch)

hit-testing具体实现

  • 调用hitTest:withEvent: 来得到一个包含触碰点的view hierarchy中最远的view
    • hitTest:withEvent:‘向自身发送pointInside:withEvent:`消息,如果返回YES,说明触碰点包含在自身的Bounds中
    • 然后递归地去遍历对于pointInside:withEvent:返回YES的subview

关于Responder Chain

屏幕快照 2016-08-26 上午12.11.29

Gesture Recognizers

  • Gesture recognizers convert low-level event handling code into higher-level actions.

屏幕快照 2016-08-22 下午4.13.49

使用

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap)];
tap.delegate = self;
[self.imageV addGestureRecognizer:tap];
  • gesture recognizer 被添加到某个view上
  • 这个这个view上发生了这样的一个手势时,手势识别器绑定的方法会被调用
  • 当一个view中添加了若干个手势识别器时,可以通过一些方法影响手势识别器捕获touch的顺序
    • 指定手势识别器分析触碰事件的优先级(如gestureRecognizer:shouldRequireFailureOfGestureRecognizer:
    • 允许两个手势识别器同时操作(如gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
    • 限制某个识别器。(如 gestureRecognizer:shouldReceiveTouch:

触碰事件的传递路径

屏幕快照 2016-08-26 上午12.49.31
从图中可以看出,当一个触碰事件发生后,

  • application从事件队列中取出原生touch event,封装成UIEvent对象,发送给window
  • window将UIEvent转发,手势识别器会优先获取该Touch,只有手势识别器未能识别出一个特定的手势时,该UIEvent才会发给对应的对应的view
  • 例子:一个双击手势的识别
    屏幕快照 2016-08-26 上午12.59.40

    • 特别注意:当手势识别器成功识别一个手势后,view会收到 touchesCancelled:withEvent:消息

改变Touch传递到view的方式

  • delaysTouchesBegan (default of NO
  • delaysTouchesEnded (default of YES)

手势识别过程

有限状态机
屏幕快照 2016-08-22 下午8.38.51

屏幕快照 2016-08-22 下午8.38.55

UIControl Event

屏幕快照 2016-08-22 下午9.08.18

更高的封装,更具体化的使用。通过target-action实现了某些UIControl子类的特定事件发生时的对应方法的调用

  • 通过addTarget:action:forControlEvents:为UIControl子类添加target和action
  • 如果某个action message对应的target为nil,那么application 会顺着responder chain直到找到一个能处理该message的对象

专业素养很重要!!!!

原文地址:https://www.cnblogs.com/rainySue/p/guan-yu-shi-jian-chuan-di-de-zong-jie.html