連續(xù)手勢和非連續(xù)手勢
連續(xù)手勢 | 非連續(xù)手勢 |
---|---|
UITapGestureRecognizer | UIPinchGestureRecognizer,UIPanGestureRecognizer ,UISwipeGestureRecognizer,UIRotationGestureRecognizer,UILongPressGestureRecognizer |
連續(xù)手勢和非連續(xù)手勢狀態(tài)變化
有限狀態(tài)機(jī)跟事件響應(yīng)鏈來比剂癌,GestureRecognizer對touch的響應(yīng)有更高的優(yōu)先級
當(dāng)觸摸事件發(fā)生時(shí),UITouches 觸摸對象會(huì)先由 UIApplication 對象傳遞給UIWindow 對象翰绊,然后佩谷,首先傳遞給點(diǎn)擊視圖的GestureRecognizer,再傳遞給視圖的事件響應(yīng)鏈监嗜。
UIWindow 對象會(huì)延遲將“觸摸”對象發(fā)送給視圖對象谐檀,從而讓手勢識(shí)別器最先對“觸摸”進(jìn)行分析處理。在延遲期間裁奇,如果識(shí)別器識(shí)別出來觸摸手勢桐猬,UIWindow 對象就不會(huì)將“觸摸對象”傳遞給視圖對象了,并將識(shí)別出來的手勢序列中其他之前本該發(fā)送給視圖對象的觸摸對象Cancel掉刽肠。
例如雙擊事件調(diào)用過程
申明兩個(gè)識(shí)別器的特定順序
假設(shè)開發(fā)者想要識(shí)別用戶的“滑動(dòng)”(swipe)手勢和“平移”(pan)手勢溃肪,而這兩個(gè)手勢需要觸發(fā)兩個(gè)不同的消息。默認(rèn)情況下五垮,當(dāng)用戶進(jìn)“滑動(dòng)”(swipe)操作時(shí)乍惊,這個(gè)手勢會(huì)被默認(rèn)識(shí)別為“平移”(pan)。這是因?yàn)椤盎瑒?dòng)”手勢操作在被系統(tǒng)識(shí)別為“滑動(dòng)”手勢(這是一個(gè)持久的連續(xù)性手勢)之前放仗,系統(tǒng)進(jìn)行判斷時(shí)润绎,發(fā)現(xiàn)其操作行為完全符合“平移”(這是一個(gè)瞬發(fā)的非持續(xù)手勢)操作的所有必要的屬性條件,所以系統(tǒng)就將其識(shí)別為“平移”诞挨。
如果開發(fā)者想要其視圖對象同時(shí)識(shí)別這兩個(gè)手勢莉撇,就需要先讓“滑動(dòng)”手勢識(shí)別器先對手勢操作進(jìn)行識(shí)別,然后進(jìn)行“平移”操作的識(shí)別惶傻。假如“滑動(dòng)”手勢確定用戶的手勢觸摸操作為“滑動(dòng)”棍郎,另外一個(gè)手勢識(shí)別器就不需要繼續(xù)分析了。如果“滑動(dòng)”識(shí)別器分析發(fā)現(xiàn)用戶手勢操作不是非持續(xù)的“滑動(dòng)”手勢银室,就會(huì)轉(zhuǎn)向失敗狀態(tài)涂佃,此時(shí)励翼,平移手勢就開始對用戶操作進(jìn)行分析了
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
[self.panRecognizer requireGestureRecognizerToFail:self.swipeRecognizer];
}
禁止GestureRecognizer 截獲觸摸事件
默認(rèn)情況下,GestureRecognizer會(huì)阻斷事件響應(yīng)鏈中的touch傳遞辜荠,即
UIGestureRecognizerDelegate中的
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
返回YES汽抚,表示touch在GestureRecognizer識(shí)別成功后會(huì)在事件響應(yīng)鏈中走touch Cancel
如果想讓touch在GestureRecognizer識(shí)別成功后仍然走到touchEnd,即GestureRecognizer和事件響應(yīng)鏈同時(shí)進(jìn)行(GestureRecognizer不截獲touch)伯病,那只需要在這個(gè)代理方法中返回NO
常見用法:
父視圖綁定的gestureRecognizer會(huì)截獲touch在子視圖響應(yīng)鏈的傳遞造烁,導(dǎo)致子視圖無點(diǎn)擊效果
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//只有g(shù)estureRecognizer綁定的view會(huì)截獲touch,阻止touch在事件響應(yīng)鏈中的傳遞
if (touch.view == gestureRecognizer.view)
{
return YES;
}
//gestureRecognizer綁定view的子視圖仍然會(huì)接收到事件響應(yīng)鏈傳來的touch午笛,并走到touchEnd
return NO;
}
UIControl的特殊性
gestureRecognizer識(shí)別是通過事件傳遞流程逐層下發(fā)惭蟋,但是如果發(fā)現(xiàn)點(diǎn)擊事件的view是UIControl或者其子類,則直接由UIWindow下發(fā)事件药磺,即UIControl比gestureRecognizer優(yōu)先級更高告组,如果UIControl既有g(shù)estureRecognizer,也有target-action癌佩,優(yōu)先響應(yīng)target-action惹谐,適用于以下情況:
? 單根手指在 UIButton,UISwitch驼卖,UIStepper,UISegementedControl 和 UIPageControl
上的單擊事件鸿秆。
? 單根手指在 UISlider 的滑塊按鈕上并且和 UISlider 控件平行方向上的滑動(dòng)操作酌畜。
? 單根手指在 UISwitch 滑塊按鈕上并且和 UISwitch 控件同水平方向上的平移操作。