一抛蚁、概念介紹
- UIGestureRecognizer是一個抽象類,定義了所有手勢的基本行為,使用它的子類才能處理具體的手勢
UITapGestureRecognizer(輕觸,點按)
UILongPressGestureRecognizer(長按)
UISwipeGestureRecognizer(輕掃手勢)
UIRotationGestureRecognizer(旋轉(zhuǎn)手勢)
UIPanGestureRecognizer(拖拽手勢)
UIPinchGestureRecognizer(捏合手勢卤妒,縮放用)
- 使用步驟:
(1)創(chuàng)建手勢識別對象
(2)設(shè)置手勢識別屬性,例如手指數(shù)量字币,方向等
(3)將手勢識別附加到指定的視圖之上
(4)編寫手勢觸發(fā)監(jiān)聽方法
二则披、UIView 的分類
方法:
1、添加一個手勢
- (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer;
2洗出、移除一個手勢
- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer;
3士复、是否接收一個手勢觸摸事件,默認(rèn)為YES翩活,返回NO為不接收
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
三判没、UIGestureRecognizer 抽象類
屬性:
1、獲取當(dāng)前手勢狀態(tài)
@property(nonatomic,readonly) UIGestureRecognizerState state;
UIGestureRecognizerState 枚舉:
UIGestureRecognizerStatePossible 尚未識別是何種手勢操作(但可能已經(jīng)觸發(fā)了觸摸事件)隅茎,默認(rèn)狀態(tài)
UIGestureRecognizerStateBegan 手勢已經(jīng)開始,此時已經(jīng)被識別嫉沽,但是這個過程中可能發(fā)生變化辟犀,手勢操作尚未完成
UIGestureRecognizerStateChanged 手勢狀態(tài)發(fā)生改變
UIGestureRecognizerStateEnded 手勢識別操作完成(此時已經(jīng)松開手指)
UIGestureRecognizerStateCancelled 手勢被取消,恢復(fù)到默認(rèn)狀態(tài)
UIGestureRecognizerStateFailed 手勢識別失敗绸硕,恢復(fù)到默認(rèn)狀態(tài)
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded 手勢識別完成堂竟,同end
2、手勢識別是否可用
@property(nonatomic, getter=isEnabled) BOOL enabled;
3玻佩、獲取手勢觸摸的View視圖
@property(nullable, nonatomic,readonly) UIView *view;
4出嘹、是否取消觸摸控件的響應(yīng)
默認(rèn)為YES,這種情況下當(dāng)手勢識別器識別到觸摸之后咬崔,會發(fā)送touchesCancelled給觸摸到的控件以取消控件view對touch的響應(yīng)税稼,這個時候只有手勢識別器響應(yīng)touch,當(dāng)設(shè)置成NO時垮斯,手勢識別器識別到觸摸之后不會發(fā)送touchesCancelled給控件郎仆,這個時候手勢識別器和控件view均響應(yīng)touch。
注意:手勢識別和觸摸事件是同時存在的兜蠕,只是因為touchesCancelled導(dǎo)致觸摸事件失效扰肌、
@property(nonatomic) BOOL cancelsTouchesInView;
5、是否延遲發(fā)送觸摸事件給觸摸到的控件
默認(rèn)是NO熊杨,這種情況下當(dāng)發(fā)生一個觸摸時曙旭,手勢識別器先捕捉到到觸摸盗舰,然后發(fā)給觸摸到的控件,兩者各自做出響應(yīng)桂躏。如果設(shè)置為YES钻趋,手勢識別器在識別的過程中(注意是識別過程),不會將觸摸發(fā)給觸摸到的控件沼头,即控件不會有任何觸摸事件爷绘。只有在識別失敗之后才會將觸摸事件發(fā)給觸摸到的控件,這種情況下控件view的響應(yīng)會延遲約0.15ms进倍。
@property(nonatomic) BOOL delaysTouchesBegan;
6土至、如果觸摸識別失敗是否立即結(jié)束本次手勢識別的觸摸事件(讓觸摸控件去識別觸摸事件)
默認(rèn)為YES,這種情況下發(fā)生一個觸摸時猾昆,在手勢識別成功后陶因,發(fā)送給touchesCancelled消息給觸摸控件view,手勢識別失敗時垂蜗,會延遲大概0.15ms楷扬,期間沒有接收到別的觸摸才會發(fā)送touchesEnded觸摸結(jié)束方法,如果設(shè)置為NO贴见,則不會延遲烘苹,即會立即發(fā)送touchesEnded以結(jié)束當(dāng)前觸摸。
@property(nonatomic) BOOL delaysTouchesEnded;
7片部、 UIGestureRecognizerDelegate 代理
@property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate;
方法:
1镣衡、創(chuàng)建一個手勢對象并添加觸發(fā)事件
- (instancetype)initWithTarget:(nullableid)target action:(nullableSEL)action;
2、給一個手勢對象添加監(jiān)聽事件
- (void)addTarget:(id)target action:(SEL)action;
3档悠、移除一個手勢的監(jiān)聽事件
- (void)removeTarget:(nullable id)target action:(nullable SEL)action;
4廊鸥、指定一個手勢需要另一個手勢執(zhí)行失敗才會執(zhí)行,同時觸發(fā)多個手勢使用其中一個手勢的解決辦法
有時手勢是相關(guān)聯(lián)的辖所,如單機和雙擊惰说,點擊和長按,點下去瞬間可能只會識別到單擊無法識別其他缘回,該方法可以指定某一個 手勢吆视,即便自己已經(jīng)滿足條件了,也不會立刻觸發(fā)酥宴,會等到該指定的手勢確定失敗之后才觸發(fā)
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
例子:
// 關(guān)鍵在這一行揩环,如果雙擊確定偵測失敗才會觸發(fā)單擊
[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];
5、獲取當(dāng)前觸摸在指定視圖上的點
- (CGPoint)locationInView:(nullable UIView*)view;
6幅虑、獲取觸摸手指數(shù)
- (NSUInteger)numberOfTouches;
7丰滑、多指觸摸的觸摸點相對于指定視圖的位置
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;
四、UIGestureRecognizerDelegate 代理方法
處理一些同時進行的手勢操作:
1、 開始進行手勢識別時調(diào)用的方法褒墨,返回NO則結(jié)束識別炫刷,不再觸發(fā)手勢,用處:可以在控件指定的位置使用手勢識別
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
2郁妈、手指觸摸屏幕后回調(diào)的方法浑玛,返回NO則不再進行手勢識別,方法觸發(fā)等
此方法在window對象在有觸摸事件發(fā)生時噩咪,調(diào)用gesture recognizer的touchesBegan:withEvent:方法之前調(diào)用顾彰,如果返回NO,則gesture recognizer不會看到此觸摸事件。(默認(rèn)情況下為YES)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
例子:UITapGestureRecognizer和UIButton的點擊事件沖突的解決辦法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isKindOfClass:[UIButton class]]) {
return NO; }
return YES;
}
3胃碾、手指按壓屏幕后回調(diào)的方法涨享,返回NO則不再進行手勢識別,方法觸發(fā)等
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press;
4仆百、 是否支持多手勢觸發(fā)厕隧,返回YES,則可以多個手勢一起觸發(fā)方法俄周,返回NO則為互斥
是否允許多個手勢識別器共同識別吁讨,一個控件的手勢識別后是否阻斷手勢識別繼續(xù)向下傳播,默認(rèn)返回NO峦朗;如果為YES建丧,響應(yīng)者鏈上層對象觸發(fā)手勢識別后,如果下層對象也添加了手勢并成功識別也會繼續(xù)執(zhí)行波势,否則上層對象識別后則不再繼續(xù)傳播
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
5翎朱、下面這個兩個方法也是用來控制手勢的互斥執(zhí)行的
(1) 這個方法返回YES,第一個手勢和第二個互斥時艰亮,第一個會失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
(2) 這個方法返回YES,第一個和第二個互斥時挣郭,第二個會失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
五迄埃、UITapGestureRecognizer(輕觸,點按)
1兑障、 設(shè)置能識別到手勢的最少的輕觸次數(shù)(默認(rèn)為1)
@property (nonatomic) NSUInteger numberOfTapsRequired;
2侄非、 設(shè)置能識別到手勢的最少的手指的個數(shù)(默認(rèn)為1)
@property (nonatomic) NSUInteger numberOfTouchesRequired;
例子:
// 創(chuàng)建一個手勢對象
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
// 設(shè)置能識別到手勢的最少的輕觸次數(shù)
tap.numberOfTapsRequired = 3;
// 設(shè)置能識別到手勢的最少的手指的個數(shù)
tap.numberOfTouchesRequired = 2;
//把手勢對象添加到對應(yīng)的控件中
[self.imgView addGestureRecognizer:tap];
六、UILongPressGestureRecognizer(長按手勢)
1流译、最少觸摸次數(shù)逞怨,默認(rèn)為0
@property (nonatomic) NSUInteger numberOfTapsRequired;
2、最少觸摸手指個數(shù)福澡,默認(rèn)為1
@property (nonatomic) NSUInteger numberOfTouchesRequired;叠赦、
3、 設(shè)置能識別到長按手勢的最短的長按時間革砸,單位:秒除秀,默認(rèn)為0.5
@property (nonatomic) CFTimeInterval minimumPressDuration;
4糯累、設(shè)置長按時允許移動的最大距離,單位:像素,默認(rèn)為10像素
@property (nonatomic) CGFloat allowableMovement;
例子:
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
// 設(shè)置能識別到長按手勢的最小的長按時間
longPress.minimumPressDuration = 0.5;
// "容錯的范圍"
longPress.allowableMovement = 10;
// 把長按手勢添加到對應(yīng)的控件中
[self.imgView addGestureRecognizer:longPress];
七、UISwipeGestureRecognizer(輕掃手勢)
1脚线、最少觸摸手指個數(shù)权旷,默認(rèn)為1
@property(nonatomic) NSUInteger numberOfTouchesRequired;
2、設(shè)置輕掃手勢支持的方向馆匿,默認(rèn)為向右滑
@property(nonatomic) UISwipeGestureRecognizerDirection direction;
枚舉值:
UISwipeGestureRecognizerDirectionRight 向右滑
UISwipeGestureRecognizerDirectionLeft 向左滑
UISwipeGestureRecognizerDirectionUp 向上滑
UISwipeGestureRecognizerDirectionDown 向下滑
例子:
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.imgView addGestureRecognizer:swipeLeft];
八、UIRotationGestureRecognizer(旋轉(zhuǎn)手勢)
1、旋轉(zhuǎn)的角度
@property (nonatomic) CGFloat rotation;
2阎肝、旋轉(zhuǎn)速度,單位:度/秒业稼、
@property (nonatomic,readonly) CGFloat velocity;
例子:
//為圖片框添加一個旋轉(zhuǎn)手勢
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateAction:)];rotation.delegate = self;
[self.imgView addGestureRecognizer:rotation];
// 旋轉(zhuǎn)手勢的監(jiān)聽方法
- (void)rotateAction:(UIRotationGestureRecognizer *)recognizer {
// 在原來的基礎(chǔ)上, 累加多少度
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
// 每次旋轉(zhuǎn)完畢后將rotation的值, 恢復(fù)到0的位置.recognizer.rotation = 0;
}
九盗痒、UIPanGestureRecognizer(拖拽手勢)
1、設(shè)置觸發(fā)拖拽最少手指數(shù)低散,默認(rèn)為1
@property (nonatomic) NSUInteger minimumNumberOfTouches;
2俯邓、設(shè)置觸發(fā)拖拽最多手指數(shù),默認(rèn)為 UINT_MAX 無限大
@property (nonatomic) NSUInteger maximumNumberOfTouches;
3熔号、獲取當(dāng)前拖拽位置
- (CGPoint)translationInView:(nullable UIView *)view;
4稽鞭、設(shè)置當(dāng)前拖拽位置
- (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view;
5、設(shè)置拖拽速度引镊,單位:像素/秒
- (CGPoint)velocityInView:(nullable UIView *)view;
例子:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[self.imgView addGestureRecognizer:pan];
// 拖拽手勢的監(jiān)聽方法
- (void)panAction:(UIPanGestureRecognizer *)recognizer {
// 1. 獲取手指拖拽的時候, 平移的值
CGPoint translation = [recognizer translationInView:recognizer.view];
// 2. 讓當(dāng)前控件做響應(yīng)的平移
recognizer.view.transform = CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y);
// 3. 每次平移手勢識別完畢后, 讓平移的值不要累加
[recognizer setTranslation:CGPointZero inView:recognizer.view];
}
十朦蕴、UIPinchGestureRecognizer(捏合手勢,縮放用)
1弟头、設(shè)置縮放比例
@property (nonatomic) CGFloat scale;
2吩抓、獲取捏合速度,單位:縮放比/秒
@property (nonatomic,readonly) CGFloat velocity;
例子:
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchAction:)];pinch.delegate = self;
[self.imgView addGestureRecognizer:pinch];
// 捏合手勢監(jiān)聽方法
- (void)pinchAction:(UIPinchGestureRecognizer *)recognizer {
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1.0;
}