一:首先查看一下關於UIGestureRecognizer的定義ui
//當前手勢狀態 typedef NS_ENUM(NSInteger, UIGestureRecognizerState) { //還沒有識別是何種手勢操做(但可能已經觸發了觸摸事件),默認狀態 UIGestureRecognizerStatePossible, //手勢已經開始,此時已經被識別,可是這個過程當中可能發生變化,手勢操做還沒有完成 UIGestureRecognizerStateBegan, //手勢狀態發生改變 UIGestureRecognizerStateChanged, // 手勢識別操做完成(此時已經鬆開手指) UIGestureRecognizerStateEnded, //手勢被取消,恢復到默認狀態 UIGestureRecognizerStateCancelled, //手勢識別失敗,恢復到默認狀態 UIGestureRecognizerStateFailed, //手勢識別完成,同end UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded }; NS_CLASS_AVAILABLE_IOS(3_2) @interface UIGestureRecognizer : NSObject //建立一個手勢對象並添加觸發事件 - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER; //給一個手勢對象添加監聽事件 - (void)addTarget:(id)target action:(SEL)action; //移除一個手勢的監聽事件 - (void)removeTarget:(nullable id)target action:(nullable SEL)action; //獲取當前手勢狀態 @property(nonatomic,readonly) UIGestureRecognizerState state; //委託 @property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate; //手勢識別是否可用 @property(nonatomic, getter=isEnabled) BOOL enabled; //獲取手勢觸摸的View視圖 只讀 @property(nullable, nonatomic,readonly) UIView *view; //是否取消觸摸控件的響應 默認爲YES,這種狀況下當手勢識別器識別到觸摸以後,會發送touchesCancelled給觸摸到的控件以取消控件view對touch的響應,這個時候只有手勢識別器響應touch,當設置成NO時,手勢識別器識別到觸摸以後不會發送touchesCancelled給控件,這個時候手勢識別器和控件view均響應touch。 注意:手勢識別和觸摸事件是同時存在的,只是由於touchesCancelled致使觸摸事件失效、 @property(nonatomic) BOOL cancelsTouchesInView; //是否延遲發送觸摸事件給觸摸到的控件 默認是NO,這種狀況下當發生一個觸摸時,手勢識別器先捕捉到到觸摸,而後發給觸摸到的控件,二者各自作出響應。若是設置爲YES,手勢識別器在識別的過程當中(注意是識別過程),不會將觸摸發給觸摸到的控件,即控件不會有任何觸摸事件。只有在識別失敗以後纔會將觸摸事件發給觸摸到的控件,這種狀況下控件view的響應會延遲約0.15ms。 @property(nonatomic) BOOL delaysTouchesBegan; //若是觸摸識別失敗是否當即結束本次手勢識別的觸摸事件 @property(nonatomic) BOOL delaysTouchesEnded; //指定一個手勢須要另外一個手勢執行失敗纔會執行,同時觸發多個手勢使用其中一個手勢的解決辦法 有時手勢是相關聯的,如單機和雙擊,點擊和長按,點下去瞬間可能只會識別到單擊沒法識別其餘,該方法能夠指定某一個 手勢,即使本身已經知足條件了,也不會馬上觸發,會等到該指定的手勢肯定失敗以後才觸發 - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer; //獲取當前觸摸在指定視圖上的點 - (CGPoint)locationInView:(nullable UIView*)view; //獲取觸摸手指數 - (NSUInteger)numberOfTouches; //多指觸摸的觸摸點相對於指定視圖的位置 - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view; @end
UIGestureRecognizer是一個抽象類,定義了全部手勢的基本行爲,使用它的子類才能處理具體的手勢atom
知識點1:關於UIGestureRecognizer的子類以下(下面這些纔是咱們日常會直接運用到的類):spa
UITapGestureRecognizer(輕觸,點按) UILongPressGestureRecognizer(長按) UISwipeGestureRecognizer(輕掃手勢) UIRotationGestureRecognizer(旋轉手勢) UIPanGestureRecognizer(拖拽手勢) UIPinchGestureRecognizer(捏合手勢,縮放用)
實例以下:代理
//拖拽手勢 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [tagButton addGestureRecognizer:pan]; - (void)pan:(UIPanGestureRecognizer *)pan { }
//給視圖增長點擊動做 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapHandle:)]; [self.view addGestureRecognizer:tap]; -(void)tapHandle:(UITapGestureRecognizer*)tap { }
二:關於UIGestureRecognizerDelegate代理的內容code
@protocol UIGestureRecognizerDelegate <NSObject> @optional //開始進行手勢識別時調用的方法,返回NO則結束識別,再也不觸發手勢,用處:能夠在控件指定的位置使用手勢識別 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer; //是否支持多手勢觸發,返回YES,則能夠多個手勢一塊兒觸發方法,返回NO則爲互斥 是否容許多個手勢識別器共同識別,一個控件的手勢識別後是否阻斷手勢識別繼續向下傳播,默認返回NO;若是爲YES,響應者鏈上層對象觸發手勢識別後,若是下層對象也添加了手勢併成功識別也會繼續執行,不然上層對象識別後則再也不繼續傳播 - (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); //手指觸摸屏幕後回調的方法,返回NO則再也不進行手勢識別,方法觸發等 此方法在window對象在有觸摸事件發生時,調用gesture recognizer的touchesBegan:withEvent:方法以前調用,若是返回NO,則gesture recognizer不會看到此觸摸事件。(默認狀況下爲YES) - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch; @end
知識點1:orm
//是否同時支持多種手勢 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES; } //是否容許開始點擊 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ return YES; } //設置點擊的範圍 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ //獲取當前的觸摸點 CGPoint curp = [touch locationInView:self.imageView]; if (curp.x <= self.imageView.bounds.size.width*0.5) { return NO; }else{ return YES; } }
知識點2:UITapGestureRecognizer和UIButton的點擊事件衝突的解決辦法對象
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ if ([touch.view isKindOfClass:[UIButton class]]) { return NO; } return YES; }
三:關於UIGestureRecognizer的子類知識blog
1:UITapGestureRecognizer(輕觸,點按)事件
NS_CLASS_AVAILABLE_IOS(3_2) @interface UITapGestureRecognizer : UIGestureRecognizer //設置能識別到手勢的最少的輕觸次數(默認爲1) @property (nonatomic) NSUInteger numberOfTapsRequired; //設置能識別到手勢的最少的手指的個數(默認爲1) @property (nonatomic) NSUInteger numberOfTouchesRequired; @end
知識點1:實例代碼以下圖片
// 建立一個手勢對象 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)]; // 設置能識別到手勢的最少的輕觸次數 tap.numberOfTapsRequired = 3; // 設置能識別到手勢的最少的手指的個數 tap.numberOfTouchesRequired = 2; //把手勢對象添加到對應的控件中 [self.imgView addGestureRecognizer:tap];
2:UILongPressGestureRecognizer(長按手勢)
NS_CLASS_AVAILABLE_IOS(3_2) @interface UILongPressGestureRecognizer : UIGestureRecognizer //設置能識別到手勢的最少的輕觸次數(默認爲1) @property (nonatomic) NSUInteger numberOfTapsRequired; //設置能識別到手勢的最少的手指的個數(默認爲1) @property (nonatomic) NSUInteger numberOfTouchesRequired; //設置能識別到長按手勢的最短的長按時間,單位:秒,默認爲0.5 @property (nonatomic) CFTimeInterval minimumPressDuration; //設置長按時容許移動的最大距離,單位:像素,默認爲10像素 @property (nonatomic) CGFloat allowableMovement; @end
知識點1:實例代碼以下
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)]; // 設置能識別到長按手勢的最小的長按時間 longPress.minimumPressDuration = 0.5; // "容錯的範圍" longPress.allowableMovement = 10; // 把長按手勢添加到對應的控件中 [self.imgView addGestureRecognizer:longPress];
3:UISwipeGestureRecognizer(輕掃手勢)
typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) { UISwipeGestureRecognizerDirectionRight = 1 << 0, //向右滑 UISwipeGestureRecognizerDirectionLeft = 1 << 1, //向左滑 UISwipeGestureRecognizerDirectionUp = 1 << 2, //向上滑 UISwipeGestureRecognizerDirectionDown = 1 << 3 //向下滑 }; NS_CLASS_AVAILABLE_IOS(3_2) @interface UISwipeGestureRecognizer : UIGestureRecognizer //最少觸摸手指個數,默認爲1 @property(nonatomic) NSUInteger numberOfTouchesRequired; //設置輕掃手勢支持的方向,默認爲向右滑 @property(nonatomic) UISwipeGestureRecognizerDirection direction; @end
知識點1:實例代碼以下
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)]; swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft; [self.imgView addGestureRecognizer:swipeLeft];
4:UIRotationGestureRecognizer(旋轉手勢)
NS_CLASS_AVAILABLE_IOS(3_2) @interface UIRotationGestureRecognizer : UIGestureRecognizer //旋轉的角度 @property (nonatomic) CGFloat rotation; //旋轉速度,單位:度/秒、 @property (nonatomic,readonly) CGFloat velocity; @end
知識點1:實例代碼以下
//爲圖片框添加一個旋轉手勢 UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateAction:)];rotation.delegate = self; [self.imgView addGestureRecognizer:rotation]; // 旋轉手勢的監聽方法 - (void)rotateAction:(UIRotationGestureRecognizer *)recognizer { // 在原來的基礎上, 累加多少度 recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation); // 每次旋轉完畢後將rotation的值, 恢復到0的位置.recognizer.rotation = 0; }
5:UIPanGestureRecognizer(拖拽手勢)
NS_CLASS_AVAILABLE_IOS(3_2) @interface UIPanGestureRecognizer : UIGestureRecognizer //設置觸發拖拽最少手指數,默認爲1 @property (nonatomic) NSUInteger minimumNumberOfTouches; //設置觸發拖拽最多手指數,默認爲 UINT_MAX 無限大 @property (nonatomic) NSUInteger maximumNumberOfTouches; //獲取當前拖拽位置 - (CGPoint)translationInView:(nullable UIView *)view; //設置當前拖拽位置 - (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view; //設置拖拽速度,單位:像素/秒 - (CGPoint)velocityInView:(nullable UIView *)view; @end
知識點1:實例代碼
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)]; [self.imgView addGestureRecognizer:pan]; // 拖拽手勢的監聽方法 - (void)panAction:(UIPanGestureRecognizer *)recognizer { // 1. 獲取手指拖拽的時候, 平移的值 CGPoint translation = [recognizer translationInView:recognizer.view]; // 2. 讓當前控件作響應的平移 recognizer.view.transform = CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y); // 3. 每次平移手勢識別完畢後, 讓平移的值不要累加 [recognizer setTranslation:CGPointZero inView:recognizer.view]; }
6:UIPinchGestureRecognizer(捏合手勢,縮放用)
NS_CLASS_AVAILABLE_IOS(3_2) @interface UIPinchGestureRecognizer : UIGestureRecognizer //設置縮放比例 @property (nonatomic) CGFloat scale; //獲取捏合速度,單位:縮放比/秒 @property (nonatomic,readonly) CGFloat velocity; @end
知識點1:實例代碼
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchAction:)]; pinch.delegate = self; [self.imgView addGestureRecognizer:pinch]; // 捏合手勢監聽方法 - (void)pinchAction:(UIPinchGestureRecognizer *)recognizer { recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale); recognizer.scale = 1.0; }