iOS开发攻城狮的集散地

初识iOS事情处理机制

2018-08-23  本文已影响29人  Andy_Ron

参考:
史上最详细的iOS之事件的传递和响应机制-原理篇
iOS触摸事件全家桶
史上最详细的iOS之事件的传递和响应机制-实践篇

事件的生命周期:
  事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view、寻找最合适的view的底层实现、拦截事件的处理)->找到最合适的view后事件的处理(touches方法的重写,也就是事件的响应)

iOS中的事件可以分为3大类型:
触摸事件
加速计事件
远程控制事件
这里只讨论iOS中的触摸事件。

1 响应者对象(UIResponder)

在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接受并处理事件,我们称之为“响应者对象”。UIApplication
UIViewController,UIView都继承了UIResponder,所以都能接收并处理事件。

UIResponder中处理事件的相关方法

    // 触摸事件
    open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
    open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
    open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
    open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)

    // 加速计事件
    @available(iOS 3.0, *)
    open func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?)
    @available(iOS 3.0, *)
    open func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?)
    @available(iOS 3.0, *)
    open func motionCancelled(_ motion: UIEventSubtype, with event: UIEvent?)

    // 远程控制事件
    @available(iOS 4.0, *)
    open func remoteControlReceived(with event: UIEvent?)

2 触摸事件的处理

以UIView为例说明触摸事件的处理

// 一根或者多根手指开始触摸view,系统会自动调用
open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
// 一根或者多根手指在view上移动,系统会自动调用(随着手指的移动,会持续调用该方法)
open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
// 一根或者多根手指离开view,系统会自动调用
open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
// 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用
open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)

3 UITouch对象

3.1 UITouch的属性和方法

// 触摸产生时所处的窗口
open var window: UIWindow? { get }
// 触摸产生时所处的视图
open var view: UIView? { get }
// 记录了触摸事件产生或变化时的时间,单位是秒
open var timestamp: TimeInterval { get }
// 当前触摸事件所处的状态
open var phase: UITouchPhase { get }
// 短时间内点按屏幕的次数,可以根据tapCount判断单击、双击或更多的点击
open var tapCount: Int { get }

// 返回值表示触摸在view上的位置
// 这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))
open func location(in view: UIView?) -> CGPoint
// 前一个触摸点的位置
open func previousLocation(in view: UIView?) -> CGPoint

3.2 UITouch的作用

4 iOS事件的产生

5 iOS事件的传递

默认UIImageView不能接受触摸事件,因为不允许交互,即userInteractionEnabled = NO。所以如果希望UIImageView可以交互,需要设置UIImageView的userInteractionEnabled = YES。

5.3 事件传递示例

数字表示视图的层次

6 如何寻找最合适的view

  1. 主窗口接收到应用程序传递过来的事件后,首先判断自己能否接手触摸事件。如果能,那么在判断触摸点在不在窗口自己身上
  2. 如果触摸点也在窗口身上,那么窗口会从后往前遍历自己的子控件(遍历自己的子控件只是为了寻找出来最合适的view)
  3. 遍历到每一个子控件后,又会重复上面的两个步骤(传递事件给子控件,1.判断子控件能否接受事件,2.点在不在子控件上)
  4. 如此循环遍历子控件,直到找到最合适的view,如果没有更合适的子控件,那么自己就成为最合适的view。

6.1 寻找的方法

7 事件的响应

事件的传递和响应的区别:
事件的传递是从上到下(父控件到子控件),事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件。

上一篇 下一篇

猜你喜欢

热点阅读