【轉(zhuǎn)】iOS手勢(shì)(UIGestureRecognizer)和觸摸(touche event)的區(qū)別和聯(lián)系

既然要說觸摸和手勢(shì)的區(qū)別和聯(lián)系,那咱們就需要先講一下觸摸和手勢(shì)的定義。

觸摸:

這個(gè)通過名字就知道,就是我們的手指觸碰到屏幕的事件就可以稱為觸摸。當(dāng)發(fā)生觸摸事件的時(shí)候默認(rèn)是沒有響應(yīng)動(dòng)作的。在iOS系統(tǒng)中,能夠響應(yīng)并處理事件的對(duì)象稱之為responder object, UIResponder是所有responder對(duì)象的基類,在UIResponder類中定義了處理各種事件,處理觸摸事件的編程接口如下:

– touchesBegan:withEvent:

– touchesMoved:withEvent:

– touchesEnded:withEvent:

– touchesCancelled:withEvent:

這四個(gè)方法分別處理觸摸開始事件,觸摸移動(dòng)事件,觸摸終止事件,以及觸摸跟蹤取消事件。只有重載UIResponder的這些方法才能實(shí)現(xiàn)觸摸事件的響應(yīng)。

說到觸摸事件的響應(yīng),肯定繞不過去響應(yīng)者鏈。響應(yīng)者鏈就是一系列連接的responder對(duì)象。UIApplication, UIViewController,UIView和所有繼承自UIView的UIKit類(包括UIWindow,繼承自UIView)都直接或間接的繼承自UIResponder,所以它們的實(shí)例都是responder object對(duì)象,都實(shí)現(xiàn)了上述4個(gè)方法。UIResponder中的默認(rèn)實(shí)現(xiàn)是什么都不做,但UIKit中UIResponder的直接子類(UIView,UIViewController…)的默認(rèn)實(shí)現(xiàn)是將事件沿著responder chain繼續(xù)向上傳遞到下一個(gè)responder,即nextResponder。

iOS中responder chain的結(jié)構(gòu)為:

Paste_Image.png

UIView的nextResponder屬性,如果有管理此view的UIViewController對(duì)象,則為此UIViewController對(duì)象;否則nextResponder即為其superview。

UIViewController的nextResponder屬性為其管理view的superview.

UIWindow的nextResponder屬性為UIApplication對(duì)象。

UIApplication的nextResponder屬性為nil。

iOS中發(fā)生觸摸事件的時(shí)候(當(dāng)發(fā)生觸摸事件的時(shí)候會(huì)把這個(gè)事件給到UIApplication專門處理觸摸事件的一個(gè)隊(duì)列里,個(gè)人臆測(cè),如有錯(cuò)誤請(qǐng)指正)APP就開始了尋找發(fā)生觸摸的視圖的過程,這個(gè)尋找的的順序是從底向上的過程。首先UIApplication會(huì)傳遞給UIWindow,然后再由UIWindow傳遞給頂級(jí)的視圖,頂級(jí)視圖會(huì)進(jìn)一步遍歷其所有的subviews。UIView有個(gè)函數(shù)叫hitTest,如果觸摸事件是發(fā)生在該視圖中,則該函數(shù)會(huì)返回非空UIView;然后該視圖遞歸其subviews,最后發(fā)現(xiàn)最終的subview。iOS系統(tǒng)在處理事件時(shí),通過UIApplication對(duì)象和每個(gè)UIWindow對(duì)象的sendEvent:方法將事件分發(fā)給具體處理此事件的responder對(duì)象,當(dāng)具體處理此事件的responder不處理此事件時(shí),可以通過responder chain交給上一級(jí)處理。基本的觸摸響應(yīng)的過程就先介紹到這。下面咱們來說一下手勢(shì)。

手勢(shì)

手勢(shì)相比觸碰事件的好處是可以直接使用已經(jīng)定義好的手勢(shì),開發(fā)者不用自己計(jì)算手指移動(dòng)軌跡。缺點(diǎn)就是沒辦法自定義手勢(shì),只能用系統(tǒng)已經(jīng)實(shí)現(xiàn)的手勢(shì)。如果想實(shí)現(xiàn)自己發(fā)明的某種手勢(shì)還得去用觸摸。手勢(shì)識(shí)別的基類是UIGestureRecognizer,是一個(gè)抽象類,定義了實(shí)現(xiàn)底層手勢(shì)識(shí)別行為的編程接口。衍生類如下:

UITabGestureRecognizer? ? ? ? 輕擊手勢(shì)

UIPinchGestureRecognizer? ? ? 捏合手勢(shì)

UIRotationGestureRecognizer? ? 旋轉(zhuǎn)手勢(shì)

UISwipeGestureRecognizer? 輕掃手勢(shì)

UIPanGestureRecognizer 拖拽手勢(shì)

UILongPressGestrueRecognizer 長(zhǎng)按手勢(shì)

使用手勢(shì)很簡(jiǎn)單,分為兩步:

創(chuàng)建手勢(shì)實(shí)例。當(dāng)創(chuàng)建手勢(shì)時(shí),指定一個(gè)回調(diào)方法,當(dāng)手勢(shì)開始,改變、或結(jié)束時(shí),回調(diào)方法被調(diào)用。

添加到需要識(shí)別的View中。每個(gè)手勢(shì)只對(duì)應(yīng)一個(gè)View,當(dāng)屏幕觸摸在View的邊界內(nèi)時(shí),如果手勢(shì)和預(yù)定的一樣,那就會(huì)回調(diào)方法。

我們用點(diǎn)擊手勢(shì)舉個(gè)例子:

UITapGestureRecognizer *single = [[UITapGestureRsecognizer alloc] initWithTarget:self action:@selector(singlEvent:)];

single.delegate = self;

[self.view addGestureRecognizer: single];

一個(gè)手勢(shì)只能對(duì)應(yīng)一個(gè)View,但是一個(gè)View可以有多個(gè)手勢(shì)。如果View添加了多個(gè)手勢(shì),缺省情況下,沒有對(duì)手勢(shì)的執(zhí)行順序排序,每次調(diào)用順序可能都不同。通過以下方法可以控制手勢(shì)的響應(yīng)順序。

(void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer

手勢(shì)雖然也是封裝的觸摸事件,當(dāng)發(fā)生手勢(shì)時(shí)不會(huì)觸發(fā)響應(yīng)者鏈的響應(yīng)過程,當(dāng)前的view會(huì)先攔截這個(gè)觸摸事件,然后查看是否實(shí)現(xiàn)了相關(guān)的手勢(shì)。如果有相應(yīng)的手勢(shì)就響應(yīng)手勢(shì),如果沒有才會(huì)加到觸摸的響應(yīng)者鏈里,開始觸摸事件的響應(yīng)過程。

更多手勢(shì)相關(guān)的說明請(qǐng)看官方文檔:uigesturerecognizer

說道手勢(shì)不得不說的就是UIGestureRecognizerDelegate。在此呢我只想說跟主題相關(guān)的一個(gè)代理函數(shù):

(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

此方法在window對(duì)象有觸碰事件發(fā)生時(shí),touchesBegan:withEvent:方法之前調(diào)用。如果返回NO,則GestureRecognizer忽略此觸碰事件。默認(rèn)返回YES??梢杂糜诮鼓硞€(gè)區(qū)域的手勢(shì)。

其他的請(qǐng)見官方說明:uigesturerecognizerdelegate

總結(jié):

簡(jiǎn)單總結(jié)一下吧,手勢(shì)和觸摸歸根到底是同一個(gè)事件,只不過響應(yīng)的過程不同。手勢(shì)是通過代理函數(shù)處理響應(yīng)過程的,而觸摸通過響應(yīng)者鏈處理。歡迎大家評(píng)論區(qū)討論,有什么說的不對(duì)的地方也請(qǐng)指正,謝謝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容