前言:
觸摸事件是ios四種類型事件中最常運(yùn)用到的泳叠,在學(xué)習(xí)觸摸事件之前作瞄,先了解一下以下兩個(gè)概念:UITouch對象和UIResponder響應(yīng)對象鏈。
概述:
根據(jù)繼承的關(guān)系圖析二,我們知道UIView是UIResponder的一個(gè)子類粉洼,所以,在觸摸屏幕(View)可以覆蓋UIResponder包含的四種觸摸方法叶摄,并各自處理四種不同的觸摸事件属韧。
1、一根手指或多根手指觸摸屏幕
- (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event;
每當(dāng)系統(tǒng)檢測到手指觸摸屏幕事件后蛤吓,就會(huì)創(chuàng)建UITouch對象宵喂。發(fā)生觸摸的UIWiew對象會(huì)收到該方法消息,系統(tǒng)傳入的第一個(gè)實(shí)參touches會(huì)包含所有相關(guān)的UITouch對象会傲。
2锅棕、一根手指或多根手指在屏幕上移動(dòng)(隨著手指的移動(dòng),相關(guān)的對象會(huì)持續(xù)發(fā)送該消息)
- (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event;
當(dāng)手指在屏幕上移動(dòng)時(shí)淌山,系統(tǒng)會(huì)更新相應(yīng)的UITouch對象裸燎,為其重新設(shè)置對應(yīng)的手指在屏幕上的位置。最初發(fā)生觸摸事件的那個(gè)UIView對象會(huì)收到該方法消息泼疑,系統(tǒng)傳入的第一個(gè)實(shí)參touches會(huì)包含所有相關(guān)的UITouch對象德绿,而且這些UITouch對象都是最初發(fā)生觸摸事件時(shí)創(chuàng)建的。
3、一根手指或多根手指離開屏幕
- (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event;
當(dāng)手指離開屏幕時(shí)移稳,系統(tǒng)會(huì)最后一次更新UITouch對象蕴纳,為其重新設(shè)置對應(yīng)的手指在屏幕上的位置。接著个粱,最初發(fā)生觸摸事件的UIView會(huì)收到該方法消息古毛。當(dāng)收到該消息的UIView執(zhí)行完該方法后,系統(tǒng)就會(huì)釋放和當(dāng)前事件有關(guān)的UITouch對象都许。
4稻薇、在觸摸操作正常結(jié)束前,某個(gè)系統(tǒng)事件(如有電話打進(jìn)來)打斷了觸摸過程
- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event;
在程序運(yùn)行時(shí)梭稚,我們不免經(jīng)常會(huì)遇到觸摸被中斷的情況颖低,例如電量低提示彈窗、打進(jìn)電話等弧烤,這些都是不由我們控制的忱屑,所以一般建議要實(shí)現(xiàn)touchesCancelled這個(gè)方法,一般情況下直接調(diào)用touchesEnd即可暇昂。
3D 觸摸
- (void)touchesEstimatedPropertiesUpdated:(NSSet *)touches NS_AVAILABLE_IOS(9_1);
3D Touch相關(guān)方法莺戒,當(dāng)前觸摸對象估計(jì)的觸摸特性,返回值是UITouchPropertyie
UITouch對象和事件響應(yīng)方法工作機(jī)制歸納:
1、一個(gè)UITouch對象對應(yīng)屏幕上的一根手指急波。只要手指沒有離開屏幕从铲,則UITouch對象就會(huì)一直存在,每個(gè)UITouch對象保存對應(yīng)的手指在屏幕上到的位置
2澄暮、觸摸移動(dòng)的過程中名段,最初發(fā)生觸摸的UIView都會(huì)在各個(gè)階段接收到相應(yīng)的觸摸事件消息,即當(dāng)某個(gè)UIView發(fā)生觸摸事件后泣懊,該UIView將永遠(yuǎn)擁有當(dāng)時(shí)創(chuàng)建的所有UITouch對象
3伸辟、當(dāng)某個(gè)UITouch對象的狀態(tài)發(fā)生變化時(shí),系統(tǒng)會(huì)向指定的對象發(fā)生特定的事件消息馍刮,并傳入發(fā)生變化的UITouch對象
當(dāng)應(yīng)用發(fā)生某個(gè)觸摸事件后信夫,系統(tǒng)會(huì)將該事件添加至一個(gè)由UIApplication實(shí)例管理的事件隊(duì)列,由該實(shí)例分發(fā)隊(duì)列中的事件卡啰。分發(fā)某個(gè)觸摸事件時(shí)静稻,該實(shí)例會(huì)向擁有該事件的UIView發(fā)送特定的UIResponder消息。當(dāng)多根手指在同一視圖匈辱、同一時(shí)刻振湾,執(zhí)行相同的觸摸事件時(shí),UIApplication實(shí)例會(huì)用單個(gè)消息亡脸、一次分發(fā)所有相關(guān)的UITouch對象押搪。該實(shí)例在發(fā)送特定的UIResponder消息時(shí)佛南,會(huì)傳入一個(gè)NSSet對象。該對象將包含所有相關(guān)的UITouch對象(一個(gè)UITouch對象對應(yīng)一根手指)嵌言。值得注意的是,因?yàn)閁IApplication實(shí)例對“同一時(shí)刻”的判斷很嚴(yán)格及穗,所以通常情況下摧茴,哪怕一組事件都是在很短的一段時(shí)間內(nèi)發(fā)生的,該實(shí)例也會(huì)發(fā)送多個(gè)UIResponder消息埂陆,分批發(fā)送UITouch對象苛白。
響應(yīng)對象鏈:
UIResponder對象可以接收觸摸事件,UIView是UIResponder的一個(gè)子類焚虱,除此之外购裙,UIResponder的子類還包括UIApplication、UIWindow鹃栽、UIViewController躏率。其中,UIViewController不是視圖民鼓,既不能觸摸也不能顯示薇芝,UIViewController對象是通過響應(yīng)對象鏈接收事件的。UIResponder對象擁有一個(gè)nextResponder指針丰嘉,相關(guān)的UIResponder對象能通過nextResponder指針組成一個(gè)響應(yīng)對象鏈夯到,如圖:
當(dāng)UIView對象屬于某個(gè)UIViewController對象時(shí),其nextResponder指針就會(huì)指向包含該視圖的UIViewController對象饮亏。當(dāng)UIView對象不屬于任何UIViewController對象時(shí)耍贾,其nextResponder指針就會(huì)指向該視圖的父視圖。UIViewController對象的nextResponder指針指向其父視圖路幸,頂層的父視圖是UIWindow對象荐开,UIWindow對象nextResponder指針指向UIApplication實(shí)例。