【轉(zhuǎn)】UIButton、UIGestureRecognizer和hitTest

轉(zhuǎn)載鏈接:

https://blog.csdn.net/mingC0758/article/details/110508615

UIButton、UIGestureRecognizer和hitTest

概述

父視圖是一個(gè)普通的UIView,添加了點(diǎn)擊手勢(shì)UITapGestureRecognizer;

UIButton可以點(diǎn)擊

UIView的userInteractionEnable = YES(默認(rèn)值),無手勢(shì)

UIBotton和UIView都是GeastureContainerView的子View

需求

當(dāng)點(diǎn)擊UIView時(shí),既不響應(yīng)UIButton,也不響應(yīng)GestureContainerView。

現(xiàn)狀

在沒有任何處理的情況下,點(diǎn)擊UIButton區(qū)域,不會(huì)響應(yīng)GestureContainerView,原因是:系統(tǒng)會(huì)先調(diào)用被觸摸視圖的

gestureRecognizerShouldBegin:方法,UIButton繼承自UIControl,在點(diǎn)擊的場(chǎng)景下該方法返回NO,因此點(diǎn)擊UIButton時(shí),父視圖的點(diǎn)擊手勢(shì)不會(huì)生效。

在 [gestureRecognizerShouldBegin:] 階段首先被調(diào)用的是被觸摸視圖的 [gestureRecognizerShouldBegin:] 方法,其參數(shù)是我們的 tap gesture 。而 UIButton 的 [gestureRecognizerShouldBegin:] 實(shí)現(xiàn)中,指定對(duì)非添加在自己身上的 tap gesture ,返回 false ,即不可響應(yīng)。所以點(diǎn)擊最終響應(yīng)的是 UIButton ,其下面視圖的 tap gesture 得不到響應(yīng)。如果讀者重寫 UIButton 的 [gestureRecognizerShouldBegin:] 方法,讓其返回 true ,會(huì)發(fā)現(xiàn)點(diǎn)擊 UIButton 時(shí), UIButton 沒有響應(yīng),響應(yīng)的卻是其父視圖的 tap gesture 。這也說明了 UIGesture 比 UIControl 的優(yōu)先級(jí)更高。另外, UIButton 的 [gestureRecognizerShouldBegin:] 實(shí)現(xiàn)中沒有對(duì)其他手勢(shì)做限制,即返回的 true ,所以你在 UIButton 上雙擊、滑動(dòng)時(shí),這些手勢(shì)都能得到其父視圖的識(shí)別

當(dāng)點(diǎn)擊最上層的UIView時(shí),首先默認(rèn)的userInteractionEnable = YES,因此點(diǎn)擊時(shí)間不會(huì)透?jìng)鞯経IButton;同時(shí)也因?yàn)樗旧頉]有添加任何手勢(shì)識(shí)別器,所以GestureContainerView的UITapGestureRecognizer會(huì)被觸發(fā)(手勢(shì)識(shí)別器的優(yōu)先級(jí)最高)。

解決方案

重寫UIButton和UIView的gestureRecognizerShouldBegin方法,return NO屏蔽所有手勢(shì)。

GestureContainerView設(shè)置代理方法- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch,touch.view != GestureContainerView時(shí),return NO。

其他

userInteractionEnable和hitTest的關(guān)系

userInteraction = NO的情況下可以觸發(fā)手勢(shì)嗎?不能。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

? ? if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01) {

? ? ? ? return nil;

? ? }

? ? if ([self pointInside:point withEvent:event]) {

? ? ? ? for (UIView *subview in [self.subviews reverseObjectEnumerator]) {

? ? ? ? ? ? CGPoint convertedPoint = [subview convertPoint:point fromView:self];

? ? ? ? ? ? UIView *hitTestView = [subview hitTest:convertedPoint withEvent:event];

? ? ? ? ? ? if (hitTestView) {

? ? ? ? ? ? ? ? return hitTestView;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return self;

? ? }

? ? return nil;

}

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

  • 一.觸摸、事件、響應(yīng)者 1. UITouch 源起觸摸 一個(gè)手指一次觸摸屏幕,就對(duì)應(yīng)生成一個(gè)UITouch對(duì)象。多...
    鐘華威閱讀 2,142評(píng)論 0 1
  • UIView可以說是我們?nèi)粘9ぷ髦薪佑|最多的一個(gè)對(duì)象、是所有視圖控件(不包括視圖控制器)的基類。主要的功能包括視圖...
    kirito_song閱讀 4,172評(píng)論 1 33
  • UIGesture和UIControl的前世今緣 最近發(fā)現(xiàn)很多同學(xué)都搞不清楚 UIGesture 和 UICont...
    Joey_Xu閱讀 3,377評(píng)論 1 24
  • 事件的生命周期 當(dāng)指尖觸碰屏幕的那一刻,一個(gè)觸摸事件就在系統(tǒng)中生成了。經(jīng)過IPC進(jìn)程間通信,事件最終被傳遞到了合適...
    HughKaun閱讀 1,293評(píng)論 0 4
  • 在開發(fā)過程中,大家或多或少的都會(huì)碰到令人頭疼的手勢(shì)沖突問題,正好前兩天碰到一個(gè)類似的bug,于是借著這個(gè)機(jī)會(huì)了解了...
    閆仕偉閱讀 5,683評(píng)論 2 23

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