Event Handing guide for iOS
- Touch Event
- Motion Event
- Remote Control Event
- Presses Event
- Gesture Recognizers
- Event Delivery: The Responder Chain
- Multitouch Events
- Motion Events
- Remote Control Events
Gesture Recognizers
|
UIKit Makes it Easy for Your App to Detect Gestures:
原本手指在屏幕的触控事件全都是通过UIView的范畴(非正式协议)事件来监听:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
识别成功会调用END,识别失败调用cancel,如在view上还有手势识别器的情况下,当手势识别器识别成功,touch非正式协议就会调用cacenl。
但UIKIT直接将再进行封装成各种UIGestureRecognizer用于识别一些通用的手势,甚至直接将手势应用于UIControl的子类,如UIButton、UISlider等,让其能直接相应与自身图形相关的触摸事件。这些手势识别器都是利用target-Action实现的,均将手势与事件直接一一对应。当然我们也可以自己定义自己所需的手势。
Target-Action机制与响应链机制的关系:
Target-Action,其实就是send action message to target when action happen,所以就是一种将事件与响应对象一一绑定的机制。而手势识别器就是应用了该机制,所以在初始化的时候会要求参入target与SEL两个关键参数以实现绑定,达到若某事件发生,就可以调用target-SEL实现效果。
而响应链机制就是iOS中事件传递的机制,它与Target-Action的关系是,当Target-Action中的SEL为nil,也就是对象无法处理事件时,事件就会沿着响应者链条回传。
|
Built-in Gesture Recognizers common Gestures:
UIKit定义的通用手势识别器:
|
Discrete and Continuous Gesture:
手势也分有离散手势与连续手势两种,离散手势如Tap Gesture,只会发送一次Action message。但连续手续,如Pinch Gesture就不一样,它是在手势缩放的整个过程都会连续发送action message。
|
Responding to Events with Gesture Recognizer:
添加一个手势识别器需要做的三件事:
响应离散手势与连续手势的区别:
所以手势识别的过程实际上就是一个状态机在不同的状态下切换的过程,而且每一次状态的切换都伴随着一个action send to target的过程,如下图所示:
PS:其中Recognized状态已经被End状态取代。
|
Defining How Gesture Recognizers Interact:
UIView通过一个NSArray属性gestureRecognizers来管理手势识别器,所以一个View也可以同时具有数个手势识别器,可以通过addGestureRecognizer与removeGestureRecognizer来进行添加与移除。
在默认情况下,当一个UIView同时包含若干去手势识别器,这些识别器收到touch的顺序每次都是随机的,但我们可以通过重写或者UIGestureRecognizerDelegate来实现以下的效果:
通过重写UIGestureRecognizer的子类方法或者实现delegate可以实现以上效果,而且在某些特殊场合十分重要。
如一个界面添加了swipes and pans手势识别器,这两个手势有比较多的共同点,默认模式容易识别错,所以需要特殊处理。
UIKit中UIControl的子类,不少都是已经封装好特定的手势识别器的了,为了不造成重叠,UIKIT默认若开发者继续添加了相同的手势识别器的,会旁路掉默认的手势识别器。包括以下场景:
|
Gesture Recognizer Interpret Raw Touch Events
手势识别器的原理本质上就是通过UIView通过范畴实现的非正式协议方法来实现的,如下图:
通过重写以上方法即可监听用户在View的触摸行为,其中有两个很重要的参数,UITouch与UIEvent,当iOS在有交互时间产生,UIEvent就会在响应链中传递,
而UIEvent有有两个重要枚举 UIEventType、 UIEventSubtype。
其中UIEventType的结构如下:
typedef NS_ENUM(NSInteger, UIEventType) {
UIEventTypeTouches, UIEventTypeMotion, UIEventTypeRemoteControl, UIEventTypePresses NS_ENUM_AVAILABLE_IOS(9_0),
};
UIEventSubtype的结构如下:
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,
};
从上面的数据结构可以,其实UITouch是封装在UIEvent中的,但这里非正式协议中的方法为了开发者方便把它单独抽离出来成为一个参数。
|
Regulating the Delivery of Touch to Views
默认的touch event时间传递的顺序如上图所示,很明显每个action是先经过Gesture recognize再到View的。若Gesture recognize先于View完成手势识别,那么view中的touch event分析就会进入cancel状态。
可以通过设置UIGestureRecognizer的delaysTouchesBegin、delaysTouchEnded属性来改变默认的事件传递规则,如下:
手势识别器可以通过调用
ignoreTouch:forEvent:来忽略特殊的事件。
|
Creating a Custom Gesture Recognizer
可以通过继承UIGestureRecognizer并重写以下基础方法,即可实现自定义的手势识别器:
- (void)reset;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
|
Event Delivery: The Responder Chain
当用户因操作而产生事件时,UIKIT就会创建一个UIEvent包含处理事件所需的信息,然后系统把这个事件放置到当前激活的App的时间队列里面。然后处于激活状态的UIApplication对象从任务队列中获取UIEvent并然后将其传递到key window,然后通过响应链找到能处理该事件的对象。
对于不同的UIEvent的传递方式略有不同:
|
Hit-Testing return the view where a touch occurred:
hit-test机制寻找hit-test view的例子:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
hit-test机制的核心方法的默认实现如下所示:
|
The responder chain is made up of responder objects
所有继承于UIResponer的对象都可以成为响应者,均具备响应处理事件的能力,而这些对象组成的链条,称为响应者链条。
响应者链条由第一响应者开始,到UIApplication结束。
第一响应者就是首先接收事件的对象,对象可以通过以下方法主动成为第一响应者:
Event不是唯一依赖响应者链条的,响应者链条常用于以下场景:
响应者链条的结构:
首先每个事件都会有自己对应的响应者链条,所以响应者链条是动态生成的。
对应Touch Event:由hit-test机制生成。
对于Motion、Remote Event:由程序设定,设定谁了first responder,然后若first responder无法响应,然后就是按照响应者链条回传,就是first responder——》。。。——》application的过程,中间的传递规律如下图。
|
The responder chain follows a specific Delivery
响应者链条是专门用于传递用户与设备交互而产生的事件,而别的系统事件是通过的别的方式来传递的,这里得区分。
响应链的传递规则图:
|
Multitouch Events
|
Creating a SubClass of UIResponder
|
implementing the Touch-event Handing method in your subclass
|
Tracking the phase and location of a touch event
|
Retrieving and Querying Touch Objects
|
Handling Tap Gestures
|
Handling Swipe and Drag Gestures
|
Handling a Complex Multitouch Sequence
|
Specifying Custom Touch Event Behavior
|
Intercepting Touches by Overriding Hit-Testing
|
Forwarding Touch Events
|
Best Practices for Handling Multitouch Events
|
Motion Events
当用设备移动、摇晃、倾斜,就会生成motion events事件。这类型的事件大多产生于iOS的硬件传感器,如:
|
Getting the Current Device Orientation with UIDevice
若想获取设备的方向,可以直接通过UIDevice实现。实例代码如下:
-(void) viewDidLoad {
// Request to turn on accelerometer and begin receiving accelerometer events
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)orientationChanged:(NSNotification *)notification {
// Respond to changes in device orientation
}
-(void) viewDidDisappear {
// Request to stop receiving accelerometer events and turn off accelerometer
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
PS:就是通过通知的方式获取设备的方向。
|
Detecting Shake-Motion Events with UIEvent
由于motion都是直接发给第一响应者,若第一响应者无法处理,则继续在响应者链条回传。
若设置了第一响应者,还得实现以下方法才能完成得到相应的数据,实现功能。
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
|
Setting and Checking Required Hardware Capabilities for Motion Events
略。
|
Capturing Device Movement with Core Motion
捕抓motion的核心数据的教程。
|
Remote Control Events
能实现用外部设备控制多媒体APP,又或者在锁屏的情况下还能控制多媒体。使用命令模式实现。
|
Preparing Your App for Remote Control Events
能接收远程控制时间,得满足以下条件:
|
Handling Remote Control Events
为特定事件添加handle的代码:
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
[commandCenter.playCommand addTargetUsingBlock:^(MPRemoteCommandEvent *event) {
// Begin playing the current track.
[[MyPlayer sharedPlayer] play];
}
|
Providing Now Playing Information
通过 MPNowPlayingInfoCenter 对象获取播放信息。
|
Testing Remote Control Events on a Device
|
Event Handing guide for iOS相关推荐
- Event Handling Guide for iOS——由触摸事件传递想到的
先帖官方文档地址 https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlin ...
- View Programming Guide for iOS官方文档翻译一
版权声明:本文为博主原创文章,转载请声明出处,谢谢! 本文档的官方英文原版地址 关于窗口和视图 在iOS中,您可以使用窗口(windows)和视图(views)在屏幕上显示APP的内容. 窗口(Win ...
- xx.xib: error: Illegal Configuration: Safe Area Layout Guide before iOS 9.0报错问题解决
之前是用xcode8.3.3创建的工程最近升级到Xcode9.0 遇见了这个问题 在Xcode 9.0以上 新建xib文件会报错 xx.xib: error: Illegal Configuratio ...
- iOS---------- Safe Area Layout Guide before iOS 9.0
如果你们的项目不做iOS9以下支持就打开main.storyboard 去除Use safe Area Layout 如果不考虑iOS9以下支持就按照下面的步骤 选中控制器,右边面板的Build ...
- iOS订阅测试终极指南The Ultimate Guide to iOS Subscription Testing
订阅测试如何测试呢?平时遇到的都是消耗型商品,没有持续性,买完就完了,而订阅型是一个持续时间段,这个时间内有很多故事发生,测试起来相对也是复杂的多.找到一篇文章,参考下: 找到并修复错误,这样你就不会 ...
- View Programming Guide for IOS:Views笔记
1.执行画图代码: "当前绘图上下文"只在执行视图的drawRect方法期间才有效.UIKit有可能会在后续调用drawRect方法时声称一个新的视图上下文,所以你不能试图去缓存这 ...
- iOS 实战开发课程笔记
iOS 实战开发课程笔记 本贴旨在作为对极客班 <iOS 开发实战>第五期期课程视频重新学习的笔记. 目标是建立一个比较完整的 iOS 开发知识点框架以及快速手册. 对各个内容的详细研究会 ...
- iOS 4层结构(iOS技术概要)—— Cocoa Touch 层(一)
苹果公司的iOS平台强力推动了iOS开发,引来了不少人从事iOS开发,也成就了一批一批的开发者,如果你是新手,请把本文作为iOS技术一览,便于你对iOS开发有个粗略的认识:如果你已经是 ...
- iOS iPhone官方参考资料明细
官方的门户站点 Refernce Library Mac OS X Refernce Library http://developer.apple.com/library/mac/navigation ...
- 深度解析~iOS应用程序~生命周期
摘要:iOS应用程序一般都是由自己编写的代码和系统框架组成,系统框架提供一些基本infrastructure给App来运行,而开发者则自己编写代码定制App的外观和行为,了解iOS Infrastru ...
最新文章
- 对ie6、ie7、ff兼容性的详细css hack介绍
- 正则学习(2)--- 简单匹配原理
- 指针系统学习7-返回指针值的函数
- 对搜狗输入法的个人评价
- VSCode从下载到配置Ubuntu系统
- jsf标签_多个动态包含一个JSF标签
- web开发要学多久,HTML表格标签,薪资翻倍
- SpringMVC redirect中文乱码问题
- python60行绘图程序_不敢相信,60行python代码就写出了贪吃蛇游戏
- intel SPR新特性CXL
- HtmlHelper、TagHelper、局部视图、视图组件
- ICNet: Intra-saliency Correlation Network for Co-Saliency Detection
- 网易互娱2022校园招聘在线笔试-游戏研发工程师(第一批)
- 隐私政策说明 - 掌上软考答题速记系统
- git push时rejected,解决non-fast-forward errors的办法
- Java 的三种技术架构
- 关于微新分享PC微信端成功,手机微信失败
- Android 之 打开相机 打开相册
- oracle ebs版本查看,Oracle EBS R12 - 如何取得EBS某个文件的版本号
- Java 使用正则表达式匹配淘口令