iOS學習筆記06 手勢識別

執著丶執念發表於2018-06-02

###一、UIGestureRecognizer簡單介紹 我們已經學習了觸控事件處理,但觸控事件處理起來很麻煩,每個觸控事件處理都需要實現3個touches方法,比較繁瑣,實際上我們可以使用更加簡單的觸控事件處理操作,那就是 手勢識別UIGestureRecognizer

手勢識別操作基類UIGestureRecognizer不能直接使用,我們常使用的是它的子類,這些手勢操作類都繼承自UIGestureRecognizer類 ######常用手勢識別子類:

  • 點按手勢 UITapGestureRecognizer
  • 捏合手勢 UIPinchGestureRecognizer
  • 拖動手勢 UIPanGestureRecognizer
  • 輕掃手勢 UISwipeGestureRecognizer【4個方向分離】
  • 旋轉手勢 UIRotationGestureRecognizer
  • 長按手勢 UILongPressGestureRecognizer

###二、UIGestureRecognizer屬性 ######物件屬性:

@property (nonatomic , readonly) UIGestureRecognizerState state;/*< 手勢狀態 */
@property (nonatomic , getter=isEnabled) BOOL enabled;/*< 手勢是否可用 */
@property (nonatomic , readonly) UIView *view;/*< 觸發手勢的檢視 */
@property (nonatomic , assign) BOOL delaysTouchesBegan;/*< 手勢識別失敗前不執行觸控開始事件,預設為NO */
複製程式碼

######手勢識別狀態state:

typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
    UIGestureRecognizerStatePossible,   // 尚未識別是何種手勢操作(但可能已經觸發了觸控事件),預設狀態
    UIGestureRecognizerStateBegan,      // 手勢已經開始,此時已經被識別,但是這個過程中可能發生變化,手勢操作尚未完成
    UIGestureRecognizerStateChanged,    // 手勢狀態發生轉變
    UIGestureRecognizerStateEnded,      // 手勢識別操作完成(此時已經鬆開手指)
    UIGestureRecognizerStateCancelled,  // 手勢被取消,恢復到預設狀態
    UIGestureRecognizerStateFailed,     // 手勢識別失敗,恢復到預設狀態
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手勢識別完成,同UIGestureRecognizerStateEnded
};
複製程式碼

左圖為 **短手勢** 的狀態轉變,右圖為 **長手勢** 的狀態轉變

###三、UIGestureRecognizer方法

#pragmX mark 新增觸控執行事件
- (void)addTarget:(id)target action:(SEL)action;
#pragma mark 移除觸控執行事件
- (void)removeTarget:(id)target action:(SEL)action;
#pragma mark 觸控點的個數(同時觸控的手指數)
- (NSUInteger)numberOfTouches;
#pragma mark 在指定檢視中的相對位置
- (CGPoint)locationInView:(UIView*)view;
#pragma mark 觸控點相對於指定檢視的位置
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView*)view;
#pragma mark 指定一個手勢需要另一個手勢執行失敗才會執行
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
複製程式碼

###四、UIGestureRecognizer使用

# 建立手勢識別器物件
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
# 設定手勢識別器物件的具體屬性
tap.numberOfTapsRequired = 2;  // 連續敲擊2次 
tap.numberOfTouchesRequired = 2;// 需要2根手指一起敲擊  
# 新增手勢識別器到對應的view上
[self.myView addGestureRecognizer:tap]; 
# 監聽手勢的觸發
[tap addTarget:self action:@selector(tapView:)]; 
複製程式碼

###五、多手勢衝突 在iOS中,如果一個手勢A的識別部分是另一個手勢B的子部分,預設情況下A就會先識別,B就無法識別了,

比如拖動手勢A和輕掃手勢B,輕掃手勢只在手勢結束狀態才能執行,而拖動手勢在手勢開始的時候執行,這兩個手勢一起觸發,輕掃手勢就成了犧牲品。

解決手勢衝突,就是利用一個方法: -(void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer 該方法指定一個手勢需要另外一個手勢識別失敗才會執行 ######比如解決拖動手勢和輕掃手勢衝突:

// 拖動手勢的執行需要右輕掃手勢的失敗為前提
[panGesture requireGestureRecognizerToFail:swipeGestureToRight];
// 拖動手勢的執行需要左輕掃手勢的失敗為前提
[panGesture requireGestureRecognizerToFail:swipeGestureToLeft];
複製程式碼

###六、UIGestureRecognizerDelegate代理 ######代理方法:

#pragma mark 一個控制元件識別手勢後是否沿著響應者鏈條繼續傳播手勢識別,預設返回NO
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
複製程式碼

用該代理方法可以實現兩個不同控制元件的手勢同時執行,需要讓該方法返回YES,手勢識別就能傳遞給不同控制元件

相關文章