你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS UIGestureRecognizer (手勢的基本知識介紹)

iOS UIGestureRecognizer (手勢的基本知識介紹)

編輯:IOS開發綜合

手勢識別在 iOS 中非常重要,他極大地提高了移動設備的使用便捷性。iOS 系統在 3.2 以後,他提供了一些常用的手勢(UIGestureRecognizer 的子類),開發者可以直接使用他們進行手勢操作。 手勢類型(他們都繼承自UIGestureRecognizer,而UIGestureRecognizer繼承自NSObject)

UIPanGestureRecognizer(拖動)
UIPinchGestureRecognizer(捏合)
UIRotationGestureRecognizer(旋轉)
UITapGestureRecognizer(點按)
UILongPressGestureRecognizer(長按)
?UISwipeGestureRecognizer(輕掃)
代碼實戰的時候,通常繼承 UIGestureRecognizer 類,實現自定義手勢(手勢識別器類)一般設計成單利對象。因為事件傳遞如果是通過Block或者是代理,那麼如果超過識別器的生命周期,手勢將不能正常響應(具體看github代碼)

-(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;
手勢的互斥的原則
1.手勢識別是具有互斥的原則的,比如單擊和雙擊,如果它識別出一種手勢,其後的手勢將不被識別。所以對於關聯手勢,要做特殊處理以幫助程序甄別,應該把當前手勢歸結到哪一類手勢裡面。
2.比如,單擊和雙擊並存時,如果不做處理,它就只能發送出單擊的消息。為了能夠識別出雙擊手勢,就需要做一個特殊處理邏輯,即先判斷手勢是否是雙擊,在雙擊失效的情況下作為單擊手勢處理。使用
[A requireGestureRecognizerToFail:B]函數,它可以指定當A手勢發生時,即便A已經滿足條件了,也不會立刻觸發,會等到指定的手勢B確定失敗之後才觸發。
    //添加雙擊手勢確定監測失敗才會觸發單擊手勢的相應操作
    [tapOne requireGestureRecognizerToFail:tapTow];
如果手勢和scrollview一起使用就要防止只相應scrollView事件
    scrollView.canCancelContentTouches=NO;
    scrollView.delaysContentTouches=NO;
手勢的幾種狀態
 typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
  // 尚未識別是何種手勢操作(但可能已經觸發了觸摸事件),默認狀態
       UIGestureRecognizerStatePossible, 
  // 手勢已經開始,此時已經被識別,但是這個過程中可能發生變化,手勢操作尚未完成
       UIGestureRecognizerStateBegan,    
 // 手勢狀態發生轉變
       UIGestureRecognizerStateChanged,
 // 手勢識別操作完成(此時已經松開手指)   
       UIGestureRecognizerStateEnded,     
// 手勢被取消,恢復到默認狀態
       UIGestureRecognizerStateCancelled,  
 // 手勢識別失敗,恢復到默認狀態
       UIGestureRecognizerStateFailed,   
// 手勢識別完成,同UIGestureRecognizerStateEnded 
       UIGestureRecognizerStateRecognized 
       UIGestureRecognizerStateEnded 
};
手勢經常用的屬性
//設置代理,具體的協議後面會說
@property(nullable,nonatomic,weak) id  delegate; 
//設置手勢是否有效
@property(nonatomic, getter=isEnabled) BOOL enabled;
//獲取手勢所在的view
@property(nullable, nonatomic,readonly) UIView *view; 
//獲取觸發觸摸的點
-(CGPoint)locationInView:(nullable UIView*)view; 
//設置觸摸點數
-(NSUInteger)numberOfTouches; 
//獲取某一個觸摸點的觸摸位置
-(CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;
//這個方法中第一個參數是需要時效的手勢,第二個是生效的手勢。
-(void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

//獲取到的是手指移動後,在相對坐標中的偏移量
-(CGPoint)translationInView:(nullable UIView *)view;

相對重要的BOOL屬性

@property(nonatomic) BOOL cancelsTouchesInView;
當這個屬性設置為YES時,如果識別到了手勢,
系統將會發送touchesCancelled:withEvent:消息在其時間傳遞鏈上,
終止觸摸事件的傳遞,
設置為NO,則不會終止事件的傳遞
@property(nonatomic) BOOL delaysTouchesBegan;
這個屬性設置手勢識別結束後,是立刻發送touchesEnded消息到事件傳遞鏈或者等待一個很短的時間後,
如果沒有接收到新的手勢識別任務,再發送。

UIGestureRecognizerDelegate

前面我們提到過關於手勢對象的協議代理,通過代理的回調,我們可以進行自定義手勢,也可以處理一些復雜的手勢關系,其中方法如下:

//手指觸摸屏幕後回調的方法,返回NO則不再進行手勢識別,方法觸發等
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
//開始進行手勢識別時調用的方法,返回NO則結束,不再觸發手勢
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
//是否支持多時候觸發,返回YES,則可以多個手勢一起觸發方法,返回NO則為互斥
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
//下面這個兩個方法也是用來控制手勢的互斥執行的
//這個方法返回YES,第一個手勢和第二個互斥時,第一個會失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
//這個方法返回YES,第一個和第二個互斥時,第二個會失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

UIGestureRecognizer的子類介紹
一、UITapGestureRecognizer(tap點按)

點擊作為最常用手勢,用於按下或選擇一個控件或條目(類似於普通的鼠標點擊); tap手勢屬於離散型手勢,特點是:一旦識別就無法取消,而且只會調用一次手勢操作事件(初始化手勢時指定的回調方法)

代碼

    //一次點擊
    UITapGestureRecognizer *tapOne = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapWithOne:)];
    tapOne.delegate = self;
    [self.view addGestureRecognizer:tapOne];
    //設置觸控對象的個數(幾個手指)
    [tapOne setNumberOfTouchesRequired:1];
    //點擊次數
    [tapOne setNumberOfTapsRequired:1];
    //兩次點擊
    UITapGestureRecognizer *tapTow = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapWithTow:)];
    tapTow.delegate = self;
    //一根手指操作
    [tapOne setNumberOfTouchesRequired:1];
    //點擊兩次生效
    tapTow.numberOfTapsRequired = 2;
    [self.view addGestureRecognizer:tapTow];
    //添加雙擊手勢確定監測失敗才會觸發單擊手勢的相應操作
    [tapOne requireGestureRecognizerToFail:tapTow];
    ```

-(void)tapWithOne: (UITapGestureRecognizer *)tapOne {
NSLog(@”被點擊了一次”);
}
-(void)tapWithTow: (UITapGestureRecognizer *)tapTow {
NSLog(@”被點擊了兩次”);
}


---
**二、 長按手勢  UILongPressGestureRecognizer**
1.屬性:

//長點擊響應前點擊次數,默認0;
@property (nonatomic) NSUInteger numberOfTapsRequired;
//__TVOS_PROHIBITED: 用戶觸摸的手指數,默認1;
@property (nonatomic) NSUInteger numberOfTouchesRequired ;
//長按最低時間,默認0.5秒;
@property (nonatomic) CFTimeInterval minimumPressDuration;
// 手指長按期間可移動的區域,默認10像素。
@property (nonatomic) CGFloat allowableMovement;


---
**三、捏合手勢 UIPinchGestureRecognizer**

1.屬性:

//縮放的比例,默認為1;
@property (nonatomic) CGFloat scale;
//縮放的速度,放大為+,縮小為-。
@property (nonatomic,readonly) CGFloat velocity;
“`

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved