iOS手势手势操作详解

JocelynLYPN 8年前

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;
    </li>
  • 该方法记录了当前一个触摸点的位置
  • 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>

    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

    • 4个触摸事件中,都有NSSet touches和UIEvent event两个参数,一次完整的触摸过程中,只会产生一个事件对象,4个触摸方法都是同一个event对象,也就是说四个方法的event都是同一个参数。
    • 如果两根手指同时触摸一个view,那么view只会调用一次touchesBegan:withEvent:方法,touches参数中装着2个UITouch对象。
    • 如果这两根手指一前一后分开触摸同一个view,那么view会分别调用2次touchesBegan:withEvent:方法,并且每次调用时的touches参数中只包含一个UITouch对象
    • 根据touches中UITouch的个数可以判断出是单点触摸还是多点触摸

    **转载请注明来自吃饭睡觉撸码的博客 http://www.cnblogs.com/Erma-king/,并包含相关链接。**

    (本文暂且写到这,下面会继续更新补充。)

    </div>

    来自: http://www.cnblogs.com/Erma-king/p/5148938.html