UIGestureRecognizer與UIMenuController

UIGestureRecognizer對(duì)象會(huì)截取本應(yīng)由視圖處理的觸摸事件。當(dāng)某個(gè)UIGestureRecognizer對(duì)象識(shí)別出特定的手勢(shì)后,就會(huì)向指定的對(duì)象發(fā)送指定的消息。
 在為應(yīng)用添加手勢(shì)識(shí)別功能時(shí),需要針對(duì)特定的手勢(shì)創(chuàng)建相應(yīng)的UIGestureRecognizer子類對(duì)象,而不是直接使用UIGestureRecognizer對(duì)象。
 使用UIGestureRecognizer子類對(duì)象時(shí),除了要設(shè)置目標(biāo)動(dòng)作對(duì),還要將該子類對(duì)象“附著”在某個(gè)視圖上。當(dāng)該子類對(duì)象根據(jù)當(dāng)前附著的視圖所發(fā)生的觸摸事件識(shí)別出相應(yīng)的手勢(shì)時(shí),就會(huì)向指定的目標(biāo)對(duì)象發(fā)送指定的動(dòng)作消息。由UIGestureRecognizer對(duì)象發(fā)出的動(dòng)作消息都會(huì)遵守以下規(guī)范:

-(void)action:(UIGestureRecognizer*)gestureRecognizer;

UIGestureRecognizer對(duì)象在識(shí)別手勢(shì)時(shí),會(huì)截取本應(yīng)由其附著的視圖自行處理的觸摸事件。附著了UIGestureRecognizer對(duì)象的視圖可能不會(huì)收到常規(guī)的UIResponder消息,例如touchesBegan:withEvent:。

UIGestureRecognizer對(duì)象會(huì)截取UITouch對(duì)象

由于UIGestureRecognizer對(duì)象會(huì)通過(guò)截取觸摸事件來(lái)識(shí)別手勢(shì),因此,在UIGestureRecognizer對(duì)象識(shí)別出手勢(shì)之前,UIView會(huì)收到所有UIResponder消息。對(duì)于UITapGestureRecognizer來(lái)說(shuō),在識(shí)別出點(diǎn)擊手勢(shì)(在屏幕中的一小塊區(qū)域觸摸并迅速抬起手指)之前,UIView會(huì)收到touchesBegan:withEvent:消息;在識(shí)別出點(diǎn)擊手勢(shì)之后,UITapGestureRecognizer會(huì)自行處理相關(guān)觸摸事件,由這些觸摸事件所引發(fā)的UIResponder消息將不會(huì)再發(fā)送給UIView。直到UITapGestureRecognizer檢測(cè)出點(diǎn)擊手勢(shì)已經(jīng)結(jié)束,UIView才會(huì)重新收到UIResponder消息(touchesCancelled:withEvent:)。

//延遲touchesBegan的接收
 double  TapRecognizer.delaysTouchesBegan=YES;

如果需要為視圖添加多種手勢(shì),就需要考慮這些手勢(shì)之間的關(guān)系。雙擊手勢(shì)包含兩次單擊,為了避免UITapGestureRecognizer將雙擊事件分拆為兩個(gè)單擊事件,可以設(shè)置UITapGestureRecognizer在單擊后暫時(shí)不進(jìn)行識(shí)別,直到確定不是雙擊手勢(shì)后再識(shí)別為單擊手勢(shì)。

 [tapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
UIMenuController

UIMenuController對(duì)象可以包含一組UIMenuItem對(duì)象(菜單項(xiàng)),并能在現(xiàn)有的視圖上顯示這些UIMenuItem對(duì)象。
每個(gè)iOS應(yīng)用只有一個(gè)UIMenuController對(duì)象。當(dāng)應(yīng)用要顯示該對(duì)象時(shí),要先為它設(shè)置一組UIMenuItem對(duì)象,然后設(shè)置顯示位置(矩形區(qū)域),最后將其設(shè)置為可見。
要顯示UIMenuController對(duì)象,還要滿足一個(gè)條件:顯示UIMenuController對(duì)象的UIView對(duì)象必須是當(dāng)前UIWindow對(duì)象的第一響應(yīng)對(duì)象。
這是因?yàn)樵搶?duì)象在顯示前會(huì)枚舉所有的UIMenuItem對(duì)象,檢查第一響應(yīng)對(duì)象是否實(shí)現(xiàn)了指定的動(dòng)作方法。如果沒(méi)有實(shí)現(xiàn)該方法,UIMenuController對(duì)象就不會(huì)顯示相應(yīng)的UIMenuItem對(duì)象;如果所有UIMenuItem對(duì)象的動(dòng)作方法都沒(méi)有實(shí)現(xiàn),應(yīng)用就不會(huì)顯示UIMenuController對(duì)象。
如果要將某個(gè)自定義的UIView子類對(duì)象設(shè)置為第一響應(yīng)對(duì)象,就必須覆蓋該對(duì)象的canBecomeFirstResponder方法。

-(BOOL)canBecomeFirstResponder
{
    return YES;
}

顯示前會(huì)枚舉所有的UIMenuItem對(duì)象,檢查第一響應(yīng)對(duì)象是否實(shí)現(xiàn)了指定的動(dòng)作方法。如果沒(méi)有實(shí)現(xiàn)該方法,UIMenuController對(duì)象就不會(huì)顯示相應(yīng)的UIMenuItem對(duì)象;如果所有UIMenuItem對(duì)象的動(dòng)作方法都沒(méi)有實(shí)現(xiàn),應(yīng)用就不會(huì)顯示UIMenuController對(duì)象。
  當(dāng)某個(gè)UIGestureRecognizer子類對(duì)象觸發(fā)特定的事件后,其state屬性會(huì)發(fā)生變化。以UILongPressGestureRecognizer對(duì)象為例,和上述三種事件相對(duì)應(yīng)的state屬性分別為:UIGestureRecognizerStatePossible、UIGestureRecognizerStateBegan和UIGestureRecognizerStateEnded。
  當(dāng)某個(gè)UIGestureRecognizer子類對(duì)象的state屬性發(fā)生變化時(shí)(除了切換至UIGestureRecognizerStatePossible的情況),該對(duì)象就會(huì)向其目標(biāo)對(duì)象發(fā)送指定的動(dòng)作消息。所以當(dāng)某個(gè)長(zhǎng)按手勢(shì)開始和結(jié)束時(shí),相應(yīng)的UILongPressGestureRecognizer對(duì)象都會(huì)向其目標(biāo)對(duì)象發(fā)送同一個(gè)消息。和該消息匹配的方法可以通過(guò)UIGestureRecognizer對(duì)象的state屬性來(lái)判斷當(dāng)前的事件類型,然后根據(jù)不同的事件類型執(zhí)行不同的代碼。
  通常情況下,UIGestureRecognizer對(duì)象不會(huì)將其處理過(guò)的觸摸事件再交給其他對(duì)象來(lái)處理。一旦某個(gè)UIGestureRecognizer子類對(duì)象識(shí)別出了相應(yīng)的手勢(shì),就會(huì)“吃掉”所有相關(guān)的觸摸事件,導(dǎo)致其他UIGestureRecognizer對(duì)象沒(méi)有機(jī)會(huì)再處理這些觸摸事件。對(duì)TouchTracker,這種特性會(huì)導(dǎo)致BNRDrawView對(duì)象無(wú)法處理拖動(dòng)手勢(shì),這是因?yàn)檎麄€(gè)拖動(dòng)手勢(shì)都是在長(zhǎng)按手勢(shì)中發(fā)生的。要解決這個(gè)問(wèn)題,需要讓UILongPressGestureRecognizer對(duì)象和UIPanGestureRecognizer對(duì)象能夠同時(shí)識(shí)別手勢(shì)。
  UIGestureRecognizerDelegate協(xié)議聲明了很多方法,gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer:(如下代碼)。當(dāng)某個(gè)UIGestureRecognizer子類對(duì)象識(shí)別出特定的手勢(shì)后,如果發(fā)現(xiàn)其他的UIGestureRecognizer子類對(duì)象也識(shí)別出了特定的手勢(shì),就會(huì)向其委托對(duì)象發(fā)送gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:消息。如果相應(yīng)的方法返回YES,那么當(dāng)前的UIGestureRecognizer子類對(duì)象就會(huì)和其他UIGestureRecognizer子類對(duì)象共享UITouch對(duì)象。

-(BOOL)gestureRecognizer: (UIGestureRecognizer*) gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)other
{
    if(gestureRecognizer==self.moveRecognizer)
    {
        return YES;
        
    }
        return NO;
}
//將當(dāng)前手指的位置設(shè)置為初始手勢(shì)的位置
[gr setTranslation:CGPointZero inView:self];

現(xiàn)UIPanGestureRecognizer對(duì)象的動(dòng)作方法moveLine:。在moveLine:中,要調(diào)用UIPanGestureRecognizer對(duì)象的translationInView:方法。該方法會(huì)根據(jù)傳入的UIView對(duì)象的坐標(biāo)系,以CGPoint結(jié)構(gòu)的形式返回手指的拖動(dòng)距離。當(dāng)拖動(dòng)手勢(shì)開始時(shí),拖動(dòng)距離是0點(diǎn)(x和y都是0)。拖動(dòng)的過(guò)程中,拖動(dòng)距離會(huì)不斷發(fā)生變化(將手指移動(dòng)至窗口的最右端,x的值就會(huì)很高。將手指移回手勢(shì)的起始位置,拖動(dòng)距離就會(huì)變回0點(diǎn))。
  當(dāng)UIGestureRecognizer對(duì)象的cancelsTouchesInView屬性為NO時(shí),這個(gè)對(duì)象所依附的UIView對(duì)象仍然會(huì)收到相應(yīng)的UIResponder消息,從而有機(jī)會(huì)處理相關(guān)的UITouch對(duì)象。

UIMenuController與UIResponderStandardEditActions

如果某個(gè)UIResponder子類需要實(shí)現(xiàn)特定的“編輯”功能,就可以實(shí)現(xiàn)相應(yīng)的方法。以UITextField為例,為了能夠剪切當(dāng)前選中的文字,UITextField實(shí)現(xiàn)了cut:方法。UIResponderStandardEditActions協(xié)議聲明了所有這類“編輯”方法。
  如果某個(gè)UIView子類實(shí)現(xiàn)了UIResponderStandardEditActions協(xié)議中的方法,那么當(dāng)這個(gè)子類對(duì)象顯示UIMenuController對(duì)象時(shí),就會(huì)出現(xiàn)和這些方法相對(duì)應(yīng)的菜單項(xiàng)。這是因?yàn)樵搶?duì)象會(huì)在顯示前枚舉所有的“編輯”菜單項(xiàng),然后根據(jù)其動(dòng)作消息向視圖發(fā)送canPerformAction:withSender:消息。如果視圖實(shí)現(xiàn)了指定的方法,該消息就會(huì)返回YES,否則返回NO。UIMenuController對(duì)象會(huì)根據(jù)canPerformAction:withSender:的返回結(jié)果判斷是否應(yīng)該顯示相應(yīng)的菜單項(xiàng)。

-(BOOL)canPerformAction:(SEL) actionwithSender:(id)sender  
{  
if(action == @selector(copy:)) 
{
  returnNO;
}
 //父類的實(shí)現(xiàn)會(huì)根據(jù)目標(biāo)對(duì)象是否實(shí)現(xiàn)了特定的動(dòng)作方法,返回YES或NO 
 return  [super  canPerformAction:action  withSender:sender];
}
再談UIGestureRecognizer

13.8

?著作權(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)容