iOS手勢手勢操作詳解

JocelynLYPN 8年前發布 | 21K 次閱讀 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個,證明了互異性。

無序性和互異性這兩點類似數學上的集合。

</div>

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(觸摸取消)
  • </ul>

    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;

    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> </div>

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

     本文由用戶 JocelynLYPN 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!