UIGestureRecognizer ?手勢識別

一抛蚁、概念介紹

  • 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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赴恨,一起剝皮案震驚了整個濱河市疹娶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伦连,老刑警劉巖雨饺,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惑淳,居然都是意外死亡额港,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門歧焦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來移斩,“玉大人,你說我怎么就攤上這事√究蓿” “怎么了忍宋?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長风罩。 經(jīng)常有香客問我糠排,道長,這世上最難降的妖魔是什么超升? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任入宦,我火速辦了婚禮,結(jié)果婚禮上室琢,老公的妹妹穿的比我還像新娘乾闰。我一直安慰自己,他們只是感情好盈滴,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布涯肩。 她就那樣靜靜地躺著,像睡著了一般巢钓。 火紅的嫁衣襯著肌膚如雪病苗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天症汹,我揣著相機與錄音硫朦,去河邊找鬼。 笑死背镇,一個胖子當(dāng)著我的面吹牛咬展,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞒斩,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼破婆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胸囱?” 一聲冷哼從身側(cè)響起祷舀,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旺矾,沒想到半個月后蔑鹦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺克,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡箕宙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铺纽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柬帕。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陷寝,到底是詐尸還是另有隱情锅很,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布凤跑,位于F島的核電站爆安,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仔引。R本人自食惡果不足惜扔仓,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咖耘。 院中可真熱鬧翘簇,春花似錦、人聲如沸儿倒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夫否。三九已至彻犁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慷吊,已是汗流浹背袖裕。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留溉瓶,地道東北人急鳄。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像堰酿,于是被迫代替她去往敵國和親疾宏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容