说收ios事件之浅见

01-iOS事件介绍

  1. UIEvent
  • 每产生一个事件,就会产生一个UIEvent对象
  • UIEvent:称为事件对象,记录事件产生的时刻类型
  1. 常见属性
    • 事件类型

@property(nonatomic,readonly) UIEventType     type;

@property(nonatomic,readonly) UIEventSubtype  subtype;

/*

typedef

NS_ENUM(NSInteger, UIEventType) {

    UIEventTypeTouches,

    UIEventTypeMotion,

    UIEventTypeRemoteControl,

};

typedef

NS_ENUM(NSInteger, UIEventSubtype) {

    // available in iPhone OS 3.0

    UIEventSubtypeNone                              = 0,    

    // for UIEventTypeMotion, available in iPhone OS 3.0

    UIEventSubtypeMotionShake                       = 1,

    // for UIEventTypeRemoteControl, available in iOS 4.0

    UIEventSubtypeRemoteControlPlay                 = 100,

    UIEventSubtypeRemoteControlPause                = 101,

    UIEventSubtypeRemoteControlStop                 = 102,

    UIEventSubtypeRemoteControlTogglePlayPause      = 103,

    UIEventSubtypeRemoteControlNextTrack            = 104,  

    UIEventSubtypeRemoteControlPreviousTrack        = 105, 

    UIEventSubtypeRemoteControlBeginSeekingBackward = 106,   

    UIEventSubtypeRemoteControlEndSeekingBackward   = 107,  

    UIEventSubtypeRemoteControlBeginSeekingForward  = 108,  

    UIEventSubtypeRemoteControlEndSeekingForward    = 109,

};

*/

 

  • 事件产生的时间

@property(nonatomic,readonly) NSTimeInterval  timestamp;

  • UIEvent还提供了相应的方法可以获得在某个view上面的触摸对象(UITouch

UIResponder


  1. 响应者对象
    • iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象
    • UIApplicationUIViewControllerUIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件

UIResponder处理事件方法

UIResponder

  • UIResponder内部提供了以下方法来处理事件
  • 触摸事件

- (void)touchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event;

  • 手指按下

- (void)touchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event;

  • 手指移动

- (void)touchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event;

  • 手指抬起

- (void)touchesCancelled:(NSSet *)toucheswithEvent:(UIEvent *)event;

  • 意外中断事件(电话打扰)
  • 加速计事件

- (void)motionBegan:(UIEventSubtype)motionwithEvent:(UIEvent *)event;

- (void)motionEnded:(UIEventSubtype)motionwithEvent:(UIEvent *)event;

- (void)motionCancelled:(UIEventSubtype)motionwithEvent:(UIEvent *)event;

  • 远程控制事件

- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

UIView和UIResponder

  • UIViewUIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件

- (void)touchesBegan:(NSSet*)touches wi  thEvent:(UIEvent *)event

  • 一根或者多根手指开始触摸view,系统会自动调用view的下面方法

- (void)touchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event

  • 一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)

- (void)touchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event

  • 一根或者多根手指离开view,系统会自动调用view的下面方法

- (void)touchesCancelled:(NSSet *)toucheswithEvent:(UIEvent *)event

  • 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法

提示:touches中存放的都是UITouch对象


UITouch


  1. UITouch介绍
  • 当用户用一根手指触摸屏幕时,会创建一个与手指相关联的UITouch对象
  • 一根手指对应一个UITouch对象
  1. UITouch的作用
    • 保存着跟本次手指触摸相关的信息,比如触摸的位置、时间、阶段
    • 当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置
    • 当手指离开屏幕时,系统会销毁相应的UITouch对象
  • 提示:iPhone开发中,要避免使用双击事件!

触摸事件处理的详细过程

    1. 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列
    2. UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow
    3. 主窗口会调用hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的视图来处理触摸事件,但是这仅仅是整个事件处理过程的第一步
    4. 找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理
      • touchesBegan…
      • touchesMoved…
      • touchedEnded…
      • 这些touches方法的默认做法是将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理 

    响应者链的事件传递过程:

    1. 如果view的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图;
    2. 在视图层次结构最顶级的视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理。
    3. 如果window对象也不处理,则其将事件或消息传递给UIApplication对象;
    4. 如果UIApplication也不能处理该事件或消息,则将其丢弃。

     

    • 具体流程:





    在事件的产生和传递的过程中涉及到的方法

      • hitTest:withEvent:方法大致处理流程:
        1. 首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内:
        2. 若pointInside:withEvent:方法返回NO,说明触摸点不在当前视图内,则当前视图的hitTest:withEvent:返回nil
        3. 若pointInside:withEvent:方法返回YES,说明触摸点当前视图内,则遍历当前视图的所有子视图(subviews),调用子视图的hitTest:withEvent:方法重复前面的步骤,子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历,直到有子视图的hitTest:withEvent:方法返回非空对象或者全部子视图遍历完毕:
          1. 若第一次有子视图的hitTest:withEvent:方法返回非空对象,则当前视图的hitTest:withEvent:方法就返回此对象,处理结束
          2. 若所有子视图的hitTest:withEvent:方法都返回nil,则当前视图的hitTest:withEvent:方法返回当前视图自身(self)
        4. 最终,这个触摸事件交给主窗口的hitTest:withEvent:方法返回的视图对象去处理。
        5. 拿到这个UIView后,就调用该UIView的touches系列方法。
      1. 模拟hitTest方法实现



UIView不接收触摸事件的三种情况

  1. 不接收用户交互userInteractionEnabled = NO
  2. 隐藏hidden = YES
  3. 透明alpha = 0.0 ~ 0.01

提示UIImageViewuserInteractionEnabled默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值