iOS觸摸事件瞧毙、手勢(shì)識(shí)別原理

觸摸發(fā)生時(shí),UIWindow會(huì)有一個(gè)隊(duì)列來(lái)存放所有的觸摸事件饲常,然后再把這些事件發(fā)送給對(duì)應(yīng)的hit-test view,hit-test view會(huì)通過(guò)touch的四個(gè)函數(shù)來(lái)接收這些事件。

四個(gè)函數(shù)分別為:(began,move, end, cancel)

//touches method

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

? ? NSLog(@"%s", __func__);

? ? [super touchesBegan:touches withEvent:event];

}


- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

NSLog(@"%s", __func__);

? ? [super touchesMoved:touches withEvent:event];

}


- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

NSLog(@"%s", __func__);

? ? [super touchesEnded:touches withEvent:event];

}


- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent

*)event {

NSLog(@"%s", __func__);

? ? [super touchesCancelled:touches withEvent:event];

}

手勢(shì)識(shí)別器同樣有touch的四個(gè)函數(shù),但是手勢(shì)識(shí)別器本身并不繼承自UIResponder鞋屈,本身并不在響應(yīng)鏈里范咨,只有手勢(shì)識(shí)別器對(duì)應(yīng)的view在響應(yīng)鏈中的時(shí)候手勢(shì)識(shí)別器才會(huì)監(jiān)聽(tīng)touch事件故觅,并根據(jù)自己的touch函數(shù)識(shí)別手勢(shì),然后觸發(fā)相應(yīng)的回調(diào)函數(shù)渠啊。本質(zhì)來(lái)說(shuō)输吏,hit-test view觸摸事件的回調(diào)跟手勢(shì)識(shí)別器是兩個(gè)獨(dú)立的過(guò)程,互不干涉替蛉,手勢(shì)識(shí)別器先開(kāi)始接收touch事件贯溅。但是手勢(shì)識(shí)別中定義了三個(gè)屬性,能夠影響hit-test view觸摸事件的調(diào)用過(guò)程躲查,這三個(gè)屬性如下所示:


gesture.cancelsTouchesInView

當(dāng)值為YES時(shí)(默認(rèn)值)它浅,表示手勢(shì)識(shí)別成功后觸摸事件取消掉,即識(shí)別成功后hitTest-View會(huì)調(diào)用touchesCancelled函數(shù)镣煮。

當(dāng)值為NO時(shí)姐霍,觸摸事件會(huì)正常起作用,會(huì)正常收到touchesEnded消息典唇。


gesture.delaysTouchesBegan ?=NO;

當(dāng)值為NO時(shí)(默認(rèn)值)镊折,觸摸事件和手勢(shì)識(shí)別的過(guò)程同時(shí)進(jìn)行,當(dāng)然先會(huì)發(fā)送觸摸事件介衔,然后當(dāng)手勢(shì)識(shí)別成功時(shí)恨胚,觸摸事件會(huì)被取消掉,即識(shí)別成功后hitTest-View會(huì)調(diào)用touchesCancelled函數(shù)炎咖。

當(dāng)值為YES時(shí)赃泡,手勢(shì)識(shí)別器先接收touch事件進(jìn)行手勢(shì)識(shí)別,識(shí)別過(guò)程中hit-test view的觸摸事件會(huì)先被UIWindow hold住乘盼,當(dāng)手勢(shì)識(shí)別成功時(shí)hit-test view的觸摸事件不會(huì)調(diào)用急迂,當(dāng)手勢(shì)識(shí)別失敗時(shí)才開(kāi)始調(diào)用touchesBegan函數(shù)。


gesture.delaysTouchesEnded = YES;

此屬性差別比較小蹦肴。

當(dāng)值為YES時(shí)(默認(rèn)值)僚碎,當(dāng)手勢(shì)識(shí)別失敗時(shí)會(huì)延遲(約0.15ms)調(diào)用touchesEnded函數(shù)。

當(dāng)值為NO時(shí)阴幌,當(dāng)手勢(shì)識(shí)別失敗時(shí)會(huì)立即調(diào)用touchesEnded函數(shù)勺阐。


delaysTouchesBegan卷中、delaysTouchesEnded這兩個(gè)屬性決定是否在手勢(shì)識(shí)別過(guò)程中向hit-test view發(fā)送觸摸事件。


總結(jié):觸摸事件與手勢(shì)識(shí)別是兩個(gè)相對(duì)獨(dú)立的過(guò)程渊抽,但是手勢(shì)識(shí)別可以通過(guò)一些屬性來(lái)影響觸摸事件的調(diào)用蟆豫,一般來(lái)說(shuō)手勢(shì)識(shí)別器的回調(diào)函數(shù)會(huì)比hit-test view的觸摸事件的晚一些,因?yàn)槭謩?shì)識(shí)別器只有在手勢(shì)識(shí)別出來(lái)之后才會(huì)觸發(fā)回調(diào)函數(shù)(默認(rèn)情況下只有一個(gè)手勢(shì)識(shí)別器能夠響應(yīng))懒闷,但是手勢(shì)識(shí)別器接收touch事件的時(shí)機(jī)比hit-test view早十减。


觸摸事件過(guò)程:

觸摸開(kāi)始,找到first responder同時(shí)找到響應(yīng)鏈愤估,當(dāng)響應(yīng)鏈上沒(méi)有手勢(shì)識(shí)別器時(shí)帮辟,觸摸事件通過(guò)first responder的響應(yīng)鏈開(kāi)始傳遞,如果響應(yīng)鏈上有手勢(shì)識(shí)別器玩焰,那么手勢(shì)識(shí)別器先接收事件由驹,然后再根據(jù)手勢(shì)識(shí)別器的三個(gè)屬性來(lái)決定是否同時(shí)將觸摸事件傳給first responder。


手勢(shì)識(shí)別器原理:

手勢(shì)識(shí)別器根據(jù)自身的四個(gè)touch函數(shù)來(lái)識(shí)別手勢(shì)昔园,例如長(zhǎng)按蔓榄、滑動(dòng)等,手勢(shì)識(shí)別器并不繼承自UIResponder默刚,因此它的四個(gè)touch函數(shù)不是UIResponder中的函數(shù)甥郑,而是UIResponder中這四個(gè)函數(shù)的鏡像(說(shuō)白了就是從UIResponder的頭文件中復(fù)制粘貼過(guò)來(lái)的)。


由此可以推測(cè)UIButton的“按下”事件等也是根據(jù)四個(gè)Touch函數(shù)來(lái)實(shí)現(xiàn)的荤西,因?yàn)閁IButton繼承自UIResponder澜搅,本身自帶四個(gè)Touch函數(shù)。(經(jīng)實(shí)驗(yàn)發(fā)現(xiàn)UIButton設(shè)置為enable時(shí)皂冰,在接收到觸摸事件之后不會(huì)繼續(xù)向上傳遞觸摸事件店展,設(shè)置為disable時(shí)會(huì)向上傳遞觸摸事件,但是加在UIButton上的tap手勢(shì)不會(huì)起作用)


以下來(lái)自蘋果代碼注釋UIGestureRecognizerSubclass.h:

// mirror of the

touch-delivery methods on UIResponder

//

UIGestureRecognizers aren't in the responder chain, but observe touches

hit-tested to their view and their view's subviews

//

UIGestureRecognizers receive touches before the view to which the touch was

hit-tested

-? (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent

*)event;

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent

*)event;

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent

*)event;

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent

*)event;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秃流,一起剝皮案震驚了整個(gè)濱河市赂蕴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舶胀,老刑警劉巖概说,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嚣伐,居然都是意外死亡糖赔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門轩端,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)放典,“玉大人,你說(shuō)我怎么就攤上這事》芄梗” “怎么了壳影?”我有些...
    開(kāi)封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)弥臼。 經(jīng)常有香客問(wèn)我宴咧,道長(zhǎng),這世上最難降的妖魔是什么径缅? 我笑而不...
    開(kāi)封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任掺栅,我火速辦了婚禮,結(jié)果婚禮上纳猪,老公的妹妹穿的比我還像新娘氧卧。我一直安慰自己,他們只是感情好兆旬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布假抄。 她就那樣靜靜地躺著怎栽,像睡著了一般丽猬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上熏瞄,一...
    開(kāi)封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天脚祟,我揣著相機(jī)與錄音,去河邊找鬼强饮。 笑死由桌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邮丰。 我是一名探鬼主播行您,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼剪廉!你這毒婦竟也來(lái)了娃循?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤斗蒋,失蹤者是張志新(化名)和其女友劉穎捌斧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泉沾,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捞蚂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跷究。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姓迅。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丁存,到底是詐尸還是另有隱情色冀,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布柱嫌,位于F島的核電站锋恬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏编丘。R本人自食惡果不足惜与学,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘉抓。 院中可真熱鬧索守,春花似錦、人聲如沸抑片。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)敞斋。三九已至截汪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間植捎,已是汗流浹背衙解。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留焰枢,地道東北人蚓峦。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像济锄,于是被迫代替她去往敵國(guó)和親暑椰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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