iOS 常見的手勢沖突解決方案

iOS事件傳遞及響應鏈

第一種場景 系統(tǒng)控件和手勢的沖突

我們點擊UIButton哺壶,發(fā)現(xiàn)只響應了button的點擊事件

如何使得UIButton的點擊事件和view的手勢事件同時響應呢

可以設置tap的cancelsTouchesInView為NO秋泳,這樣Button的點擊事件和View的手勢事件都會響應

// default is YES. causes touchesCancelled:withEvent: or pressesCancelled:withEvent: to be sent to the view for all touches or presses recognized as part of this gesture immediately before the action method is called.


第二種場景?UICollectionView和點擊手勢的沖突

點擊UICollectionView的cell懊纳,發(fā)現(xiàn)cell沒有被響應瞒瘸,響應的是tap手勢事件

如果想要點擊響應的是cell的點擊事件宏所,而不是viewtap手勢雕蔽,該如何實現(xiàn)呢

? ? tap.delegate = self;

實現(xiàn)gestureRecognizer:shouldReceiveTouch:代理

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

{

?? ? // 若為UICollectionViewCell(即點擊了collectionViewCell)刊侯,

? ? if ([touch.view isKindOfClass:[UICollectionViewCell class]]) {

? ? // cell 不需要響應 父視圖的手勢,保證didselect 可以正常

? ? ? ? return NO;

? ? }

? ? //默認都需要響應

? ? return? YES;

}


第三種場景 兩個手勢間的沖突

兩個view上都加了點擊手勢芒炼,如果想兩個手勢都響應

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizershouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{

? ? return YES;

}

第四種場景 兩個scrollView的滑動沖突

項目中常遇到一種場景瘫怜,UIScrollView上增加了一個UIScrollView的子視圖,當某些條件下需要父視圖滑動,某些情況下需要子視圖滑動

例如一個UICollectionView嵌套了一個UICollectionView本刽,希望嵌套的UICollectionView在父視圖達到一定高度時鲸湃,父視圖不再滾動赠涮,而是子視圖滾動

CustomCell內也有一個collectionView(CustomCollectionView 類)

CustomCollectionView設置一個屬性customScrollEnable,用來控制當與其他手勢沖突時的優(yōu)先級暗挑,CustomCollectionView類實現(xiàn)gestureRecognizer代理

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{

? ? if (self.customScrollEnable) {

? ? ? ? returngestureRecognizer !=self.panGestureRecognizer;

? ? }

? ? returngestureRecognizer ==self.panGestureRecognizer;

}

在父視圖的scrollViewDidScroll

子視圖的scrollViewDidScroll里

這樣就可以通過兩個很簡單的判斷設置customScrollEnable屬性控制滑動手勢的優(yōu)先級

補充手勢代理

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

手勢識別器是否能夠開始識別手勢.

當手勢識別器識別到手勢,準備從UIGestureRecognizerStatePossible狀態(tài)開始轉換時.調用此代理,如果返回YES,那么就繼續(xù)識別,如果返回NO,那么手勢識別器將會將狀態(tài)置為UIGestureRecognizerStateFailed.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

gestureRecognizer : 此對象發(fā)送的代理消息.

返回YES允許gestureRecognizer與otherGestureRecognizer同時識別.

如果返回NO,分兩種情況.1.兩個手勢都返回NO,那么不會同時識別.如果一個NO,一個YES.可能會同時識別.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

一般用來重寫該方法.來定義什么時候手勢識別失敗.如果直接返回YES,那么gestureRecognizer與otherGestureRecognizer互斥的話gestureRecognizer識別失敗. 可以用tap手勢和longPress手勢試試.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

和3差不多,注意這個Be,所以是相反的,如果互斥,otherGestureRecognizer識別失敗.

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

返回手勢識別器是否允許檢查手勢對象.

UIKit將會在touchesBegan:withEvent:方法之前調用這個代理.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press;

返回手勢識別器是否允許檢查按壓(UIPress對象).

UIKit將會在touchesBegan:withEvent:方法之前調用這個代理.

我們可以通過配置手勢的屬性來改變它的表現(xiàn)笋除,下面介紹三個常用的屬性:

cancelsTouchesInView:該屬性默認是 true。顧名思義炸裆,如果設置成 false垃它,當手勢識別成功時,將不會發(fā)送 touchesCancelled 給目標視圖烹看,從而也不會打斷視圖本身方法的觸發(fā)国拇,最后的結果是手勢和本身方法同時觸發(fā)。有的時候我們不希望手勢覆蓋掉視圖本身的方法惯殊,就可以更改這個屬性來達到效果酱吝。

delaysTouchesBegan:該屬性默認是 false。在上個例子中我們得知土思,在手指觸摸屏幕之后务热,手勢處于 .possible 狀態(tài)時,視圖的 touches 方法已經開始觸發(fā)了己儒,當手勢識別成功之后崎岂,才會取消視圖的 touches 方法。當該屬性時 true 時闪湾,視圖的 touches 方法會被延遲到手勢識別成功或者失敗之后才開始冲甘。也就是說,假如設置該屬性為 true 响谓,在整個過程中識別手勢又是成功的話,視圖的 touches 系列方法將不會被觸發(fā)省艳。

delaysTouchesEnded:該屬性默認是 true娘纷。與上個屬性類似,該屬性為 true 時跋炕,視圖的 touchesEnded 將會延遲大約 0.15s 觸發(fā)赖晶。該屬性常用于連擊,比如我們需要觸發(fā)一個雙擊手勢辐烂,當我們手指離開屏幕時應當觸發(fā) touchesEnded遏插,如果這時該屬性為 false,那就不會延遲視圖的 touchesEnded 方法纠修,將會立馬觸發(fā) 胳嘲,那我們的雙擊就會被識別為兩次單擊。當該屬性是 true 時扣草,會延遲 touchesEnded 的觸發(fā)了牛,將兩次單擊連在一起颜屠,來正常識別這種雙擊手勢。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鹰祸,一起剝皮案震驚了整個濱河市甫窟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛙婴,老刑警劉巖粗井,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異街图,居然都是意外死亡浇衬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門台夺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來径玖,“玉大人,你說我怎么就攤上這事颤介∈嵝牵” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵滚朵,是天一觀的道長冤灾。 經常有香客問我,道長辕近,這世上最難降的妖魔是什么韵吨? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮移宅,結果婚禮上归粉,老公的妹妹穿的比我還像新娘。我一直安慰自己漏峰,他們只是感情好糠悼,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浅乔,像睡著了一般倔喂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上靖苇,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天席噩,我揣著相機與錄音,去河邊找鬼贤壁。 笑死悼枢,一個胖子當著我的面吹牛,可吹牛的內容都是我干的脾拆。 我是一名探鬼主播萧芙,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼给梅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了双揪?” 一聲冷哼從身側響起动羽,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渔期,沒想到半個月后运吓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡疯趟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年拘哨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片信峻。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡倦青,死狀恐怖,靈堂內的尸體忽然破棺而出盹舞,到底是詐尸還是另有隱情产镐,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布踢步,位于F島的核電站癣亚,受9級特大地震影響,放射性物質發(fā)生泄漏获印。R本人自食惡果不足惜述雾,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望兼丰。 院中可真熱鬧玻孟,春花似錦、人聲如沸鳍征。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蟆技。三九已至玩敏,卻和暖如春斗忌,著一層夾襖步出監(jiān)牢的瞬間质礼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工织阳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眶蕉,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓唧躲,卻偏偏與公主長得像造挽,于是被迫代替她去往敵國和親碱璃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內容