前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Event官方文档

Event官方文档

作者头像
nimomeng
发布2018-09-13 14:21:13
2K0
发布2018-09-13 14:21:13
举报
  1. Event是对象,它代表了一个被硬件检测到的用户行为,并且该行为传递到iOS中。
  2. UIKits当下可以识别三种类型的events:touch事件、shaking事件和remote-control事件(比如耳机控制)
  3. 永远不要retain UIEvent对象。
  4. Event Delivery流程: a) 当用户touch手机屏幕时,iOS识别了touch并打包到UIEvent对象里,并排到active application的事件队列之中。 b) 如果刺痛将shaking解析为一个motion event。 UIApplication 单例,就是会管理application的那个,会从队列top取出来一个event 对象并且dispatch,转发给handler。 c) 一般来说,UIApplication会转发给application的key window,然后window会发送这个event给一个初始化的obj以便处理。这个对象会区分为touch event和motion event: i. touch event:window obj 用hit-testing和响应链来寻找响应事件的对象。在hit-testing里,window会调用hitTest:withEvent:方法在view 树最上层的view上。这个方法会递归的调用pointInside:withEvent方法在view树的每一个会返回YES的view中。这个过程会一直进行,直到发现某个view在touch的范围内,这个view就变成了hit-testview。如果hit-test view没办法处理事件,则事件就会沿着响应链一路向上知道系统发现一个能处理的view ii. motion 和 remote-control事件:window会发送每一次的shaking-motion或者remote-control事件给first responder去处理。
  5. UIApplication对象和每一个UIWindow对象会通过sendEvent方法来派发事件。由于这些方法都是event 进入application的funnel points,所以你可以继承UIApplication或者UIWindow并且重载sendEvent方法来监控事件。如果你真的重载了,一定记得要调用super方法([super sendEvent:the Event]).
  6. UIResponse是所有responder对象的基类。它不仅仅定义的编程接口不仅为了事件处理,还为了普通响应行为。
  7. 继承链:

当系统传递一个touch event,首先会send到一个特定的view。对于touch view来讲,这个view就是被hitTest:withEvent:返回的view;对于shaking-motion event,remote-control事件,action messages,和editing-menu message, view就是firstResponder。如果initial view没有处理event,他就会沿着响应链去查找,顺序为: a) hit-test view或者firstResponder会传递event或者message到它的vc上(如果有的话);如果没有vc,则将event或者message传到superView上 b) 如果view或者vc不能handle event或者message,会传到view的superview上。 c) 之后的所有superView会根据a、b的模式进行传输,如果无法handle的话 d) view树的最上层的view,如果无法handle event或者message,会把event send到window对象 e) 如果UIWindow对象无法handle的话,会传递到application对象单例上 f) 如果application单例无法处理event或者message,则discards。

  1. 如果想要接收并处理高频率的,连续的motion data,应当使用 Core Motion accelerometer API。
  2. 触摸行为,被UITouch 对象表示,有时间和空间特性。时间特性,称之为相位,暗示了何时触摸的开始,不论他是静还是动和何时触摸结束,当手指从屏幕上抽离。空间特性指的是touch会聚合很多对象,表征touch出现过的地方。
  3. Touch事件的传递需要注意的: a) 关掉touch事件的传递。 设置userInteractionEnabled属性为NO b) 关掉一定时间内的touch事件的传递。Application能调用UIApplication的beginIgnoringInteractionEvent,之后调用endIgnoringInteractionEvents方法。所以在展示animation的时候最好关掉事件传递。 c) 限制事件传递到一个单个的view上。默认的,view的exclusiveTouch属性是NO,表示他会接收传递的事件。如果设置为YES,则在事件传递时,它不会接收事件。 d) 限制事件传递至subviews。自定义UIViewclass会重载hittest:withEvent方法去限制multitouch事件至subview。
  4. 为了能接收multitouch事件,你的子类必须实现一个或多个UIResponder方法(touch-event handling)。另外,view必须可见(不能透明或者隐藏),并且userInteractionEnabled属性为YES。
  5. 存储UITouch应当用CFDictionaryRef而不是NSDictionary,因为之后的会copy 它的keys,而UITouch类没有实现NSCopying协议。
  6. 处理Multitouch事件的最佳实践: a) 实现event-cancellation方法。防止不连续的状态的出现。 b) 如果处理的event是在UIView、UIViewController或者UIResponder的子类: i. 应当继承宿友event-handling方法; ii. 不要调用方法的super实现 c) 如果处理的是其它UIKit responder类的实现,在: i. 不要实现任何event-handling方法; ii. 一定要调用super方法,如:[super touchBegan:theTouches withEvent:theEvent]; d) 不要将event forwar到其它UIKit framework的responder 对象中。 e) 自定义类,响应event是应当只在event-handling方法里设置drawing状态,并且只在drawRect方法里去绘图。 f) 不要通过nextResponder去越级触发事件;相反,应当通过调用superClass实现来处理响应链。
  7. 手势识别中,在将事件send到hit-test view之前,window对象会把它send到和这个view或者view的subviews相关的手势识别器当中。过程如下所示。
  1. 一般来说,两个手势识别器不能同时识别手势。但是你可以通过实现gestureRecognizer:shouldRecognizeSimultaneouslyWIthGestureRecognizer:,是UIGestureRecognizerDelegate协议实现的。这个方法会在当接收器接阻断特殊识别器的操作时被调用。Return YES 当所有的手势识别器去同时识别他们的手势。
  2. Touch 事件的传递:(假设一个双指的触摸) a) Window发送连个touch 对象在 start phase(UITouchPhaseBegan)到手势识别器中,此时还未识别手势。Window会发同样的对象给手势关联的view。 b) Window发送两个touch 对象在Move phase(UITouchPhaseMoved)到手势识别器中,此时还是未识别什么手势。Window会发同样的对象给手势关联的view。 c) Window发送一个touch对象在End Phase(UITouchPhaseEnded)到手势识别器中。这个touch对象没有为确定手势获得足够的信息,但是window此时不会给关联view数据 d) Window发送逆回购touch对象在End Phase。手势识别器现在识别了手势并且设置状态为UIGestureRecognizerStateRecognized.在第一个action msg发送之前,view收到了touchCancelled:withEvent:消息,使得之前发送的消息失效。 在End Phase的touch被取消了。 e) 如果手势识别器检测到多指操作并非手势,会设置状态为UIGestureRecognizerStateFailed。
  3. 手势的状态转移 a) 所有手势都开始于UIGestureRecognizerStatePossible。之后会分析多指触摸的顺序,通过他们的hit-test view,之后要么识别出来要么识别失败。如果没有识别成功,则转为UIGestureRecognizerStateFail。这条准则不论是离散手势还是连续手势,都适用。 b) 当一个手势被识别时,连续手势的状态识别有别于离散手势。离散手势直接从Possible到Recognized(UIGestureRecognizerStateRecognized).。对于连续手势来讲,当最初识别手势,会从Possible到Began(UIGestureRecognizerStateBegan),当开始识别时。之后会从began到changd(UIGestureREcognizerStateChanged),之后每一次变化都会变为changed。最终,当最后一个手指离开屏幕时,状态变为End(UIGestureRecognizerStateEnded)。当然,也有可能会从changed到cancelled。 c) 总结下来,分别如下图: d)
  1. 要想接收motion 事件,responder对象必须是firest responder。对象要继承UIResponder,必须不近实现motionBegan:withEvent:和motionEnded:withEvent方法,也有可能是都实现。
  2. shake事件和touch事件有很大不同。当用户开始shake设备,系统会发送motion事件给first responder,通过motionBegan:withEvent:消息。如果responder没有handle事件,则他会沿着响应链向上查找。如果shaking少于一秒,则系统会发送motionEnded:withEvent:消息给firstResponder。如果shake时间太长,系统认为不是一个shake,first responder会接收一个motionCancelled:withEvent:消息。
  3. 在获取当前方向之前,你需要告诉UIDevice类,去开始收集系统的旋转通知,通过调用beginGeneratingDeviceOrientationNotifications方法。这会打开加速器硬件。之后在处理完旋转的事件之后,你可以获取当前的旋转方向,(从UIDevice)。你也可以通过UIDeviceOrientationDidChangeNotification方法,来接收旋转的通知。 在Remote-control事件的处理上,接收事件时需要将对象设置为first Responder,设置canBecomeFirstResponder去返回YES。也需要设置becomeFirstResponder:- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; [self becomeFirstResponder]; } 当vc不在管理audio或者video时,应当关掉事件窗口,注销first Responder状态。
  • (void)viewWillDisappear:(BOOL)animated { [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; [self resignFirstResponder]; [super viewWillDisappear:animated]; }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.06.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档