iOS手势手势操作详解
iOS手势手势操作详解
目录
一、UIResponder
二、UIGestureRecognizer 手势识别
三、响应链
**API原文**:Events are objects sent to an app to inform it of user actions. In iOS, events can take many forms: Multi-Touch events, motion events, and events for controlling multimedia. This last type of event is known as a remote control event because it can originate from an external accessory.
事件是发送给一个应用程序,通知用户操作它的对象。在IOS中,事件可以采取多种形式:多点触摸事件,移动事件,和控制多媒体事件。这最后一种类型的事件被称为远程控制事件,因为它可以源于外部附件。
一、UIResponder
在iOS中,只要继承于UIResponder都能处理响应者事件,UIView继承于UIResponder,而大多数空间最终都继承于UIView。在3.2版本之前,iOS处理屏幕触摸,主要由UIResponder来管理。
iOS中的事件大概分为三种:
1、触摸事件
2、加速事件
3、远程控制事件
1、触摸事件
1.1 touchesBegan,当点触摸,开始触摸。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
1.2 touchesMoved,屏幕上移动。
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
1.3 touchesEnded,抬起手指。
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
1.4 touchesCancelled,电话呼入等中断手势的事件。
- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
1.5 touchesEstimatedPropertiesUpdated,9.1之后加入的3D触摸事件。
- (void)touchesEstimatedPropertiesUpdated:(NSSet * _Nonnull)touches NS_AVAILABLE_IOS(9_1);
2、加速事件
2.1 开始加速
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
2.2 结束加速
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
2.3 加速中断
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
3、远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;
每个方法系统默认传入两个参数,一个是touches,是NSSet的类对象,一个是event,是UIEvent的类对象。先看看这两个参数的含义吧。笔者大多数都是参考苹果官方API得知的。
4、NSSet类和UITouch类。
4.1 NSSet。
4.1.1 无序性,存放到NSSet中的元素没有顺序。
代码验证:
NSSet *set1 = [NSSet setWithObjects:@(1), @"h", @"h", @(1), @"a", @"we", nil]; for (id obj in set1) { NSLog(@"%@", obj); }
控制台输出
2016-01-21 12:43:55.711 test[1662:901144] a 2016-01-21 12:43:55.711 test[1662:901144] we 2016-01-21 12:43:55.711 test[1662:901144] 1 2016-01-21 12:43:55.711 test[1662:901144] h Program ended with exit code: 0
结果可以看出存放的顺序和打印输出的顺序无关,证明了无序性。
4.1.2 互异性。存放到NSSet中的元素互不相同。
代码验证:
NSSet *set = [NSSet setWithObjects:@(1), @(2), @"aa", @"aa", nil]; NSLog(@"%@", @(set.count));
控制台输出
2016-01-21 12:47:16.815 test[1702:918703] 3 Program ended with exit code: 0
一共输入了4个对象,有一个重复对象,打印输出个数为3个,证明了互异性。
无序性和互异性这两点类似数学上的集合。
4.1.3 通过anyObject来访问单个元素。
4.1.4 通过forin循环来遍历NSSet中的每一个元素。
4.1.5 高效率。
4.2 UITouch。
4.2.1 UITouch简单介绍
用户用一根手指触摸屏幕时,系统会自动创建一个与手指相关联的UITouch对象,一根手指对应一个UITouch对象,系统会自动把这些UITouch对象存放到NSSet集合中,所以,有了上文中提到的手指移动方法中的参数touches
4.2.2 UITouch作用
保存手指触摸屏幕的一些相关信息,如触摸的位置、时间、阶段,当手在指移动时,系统会自动更新这个手指最初触摸屏幕创建的同一个UITouch对象,使得能够一直保存该手指的触摸信息。当手指离开屏幕时,系统会自动销毁相应的UITouch对象。
4.2.3 UITouch的属性
4.2.3.1 触摸产生时所处的窗口。窗口可能发生变化,当前窗口不一定是最开始触摸的窗口。
<pre>@property(nonatomic,readonly,retain) UIWindow window;</pre>4.2.3.2 触摸产生时所处的视图。视图可能发生变化,当前视图也不一定时最初的视图。
<pre>@property(nonatomic,readonly,retain) UIView view;</pre>4.2.3.3 短时间内点按屏幕的次数,可以根据tapCount判断单击、双击或更多的点击。
<pre>@property(nonatomic,readonly) NSUInteger tapCount;</pre>4.2.3.4 记录了触摸事件产生或变化时的时间,单位是秒。
<p>@property(nonatomic,readonly) NSTimeInterval timestamp;</p>4.2.3.5 当前触摸事件在某一个周期中所处的状态。
<pre>@property(nonatomic,readonly) UITouchPhase phase;</pre>phase是UITouchPhase类型的,是一个枚举,包含了:
typedef NS_ENUM(NSInteger, UITouchPhase) { UITouchPhaseBegan, // whenever a finger touches the surface. UITouchPhaseMoved, // whenever a finger moves on the surface. UITouchPhaseStationary, // whenever a finger is touching the surface but hasn't moved since the previous event. UITouchPhaseEnded, // whenever a finger leaves the surface. UITouchPhaseCancelled, // whenever a touch doesn't end but we need to stop tracking (e.g. putting device to face) };
- UITouchPhaseBegan(触摸开始)
- UITouchPhaseMoved(接触点移动)
- UITouchPhaseStationary(接触点无移动)
- UITouchPhaseEnded(触摸结束)
- UITouchPhaseCancelled(触摸取消)
4.2.4 UITouch的成员方法
- (CGPoint)locationInView:(nullable UIView *)view;
- 返回值表示触摸在当前view上的位置,这里返回的位置是相对view的坐标(以view的左上角为原点(0, 0))
注意:调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置。
---- (CGPoint)previousLocationInView:(nullable UIView *)view;
- 该方法记录了当前一个触摸点的位置
-
5、 UIEvent
每当发生一个完整的触摸事件,就会产生一个UIEvent对象,UIEvent,称为事件对象,记录事件发生的时刻和类型。
5.1 UIEvent常见属性
事件类型
@property(nonatomic,readonly) UIEventType type NS_AVAILABLE_IOS(3_0);
@property(nonatomic,readonly) UIEventSubtype subtype NS_AVAILABLE_IOS(3_0);
时间产生的时间
@property(nonatomic,readonly) NSTimeInterval timestamp;
</ul> - 4个触摸事件中,都有NSSet touches和UIEvent event两个参数,一次完整的触摸过程中,只会产生一个事件对象,4个触摸方法都是同一个event对象,也就是说四个方法的event都是同一个参数。
- 如果两根手指同时触摸一个view,那么view只会调用一次touchesBegan:withEvent:方法,touches参数中装着2个UITouch对象。
- 如果这两根手指一前一后分开触摸同一个view,那么view会分别调用2次touchesBegan:withEvent:方法,并且每次调用时的touches参数中只包含一个UITouch对象
- 根据touches中UITouch的个数可以判断出是单点触摸还是多点触摸
6、一次完整的触摸
一般情况下一次完整的触摸,会经历3个状态:
触摸开始:- (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
**转载请注明来自吃饭睡觉撸码的博客 http://www.cnblogs.com/Erma-king/,并包含相关链接。**
(本文暂且写到这,下面会继续更新补充。)