首先要搞清楚手勢的幾個BOOL值和代理方法
創(chuàng)新互聯(lián)建站于2013年開始,先為本溪等服務建站,本溪等地企業(yè),進行企業(yè)商務咨詢服務。為本溪企業(yè)網站制作PC+手機+微官網三網同步一站式服務解決您的所有建站問題。
假如現在有個tableView加在scrollView上,需求讓scrollView滾動到一定位置后在響應table的滾動事件,如下圖:
首先,手勢默認是互斥的,由事件的響應鏈可知,如果當前事件有被處理,那么事件將不會繼續(xù)向上傳遞,意味著如果滑動tableView,父試圖scrollView是不會響應的,顯然就不是我們想要的。所以首先就需支持多手勢
然后就是一些細節(jié)處理,在scrollView的代理方法里邊設置邊界值,進行簡單的邏輯處理,滑動到某一個值就停下來
這里只是簡單的一個demo,對手勢沖突的一個簡單處理,歡迎討論。
附上 Demo
我們點擊UIButton,發(fā)現只響應了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的cell,發(fā)現cell沒有被響應,響應的是tap手勢事件
如果想要點擊響應的是 cell 的點擊事件,而不是 view 的 tap 手勢,該如何實現呢
實現gestureRecognizer:shouldReceiveTouch:代理
兩個view上都加了點擊手勢,如果想兩個手勢都響應
項目中常遇到一種場景,UIScrollView上增加了一個UIScrollView的子視圖,當某些條件下需要父視圖滑動,某些情況下需要子視圖滑動
例如一個UICollectionView嵌套了一個UICollectionView,希望嵌套的UICollectionView在父視圖達到一定高度時,父視圖不再滾動,而是子視圖滾動
CustomCell內也有一個collectionView(CustomCollectionView 類)
CustomCollectionView設置一個屬性customScrollEnable,用來控制當與其他手勢沖突時的優(yōu)先級
在父視圖的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:方法之前調用這個代理.
我們可以通過配置手勢的屬性來改變它的表現,下面介紹三個常用的屬性:
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ā),將兩次單擊連在一起,來正常識別這種雙擊手勢。
1、在tableView上添加手勢,并設置手勢代理為當前控制器
2、利用代理方法- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 允許tableView上響應多手勢
3、利用代理方法- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer,控制添加的手勢是否響應
通常在tableView上添加手勢,會有沖突,比如在tableView上添加pan手勢,就會讓tableView的無法滾動,在tableViewCell上添加tap手勢,就會讓tableViewCell的didSelectCell方法無法響應等等,利用代理方法 gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 雖然能讓添加的手勢和原來的事件都響應,但是會造成一次性響應多個事件,這時候就需要用代理方法gestureRecognizerShouldBegin:來控制,添加的手勢是否需要響應,并且不會阻斷事件傳遞,這樣就能很好的解決沖突問題。
這是scrollView左右滑動與側滑手勢沖突解決方法。
其實就是判斷手勢是否繼續(xù)向下傳遞。
1.當然要自定義一個UIScrollView,在CustomScrollView的手勢代理方法里實現自己的邏輯
之前寫過類似的( ),這里就當溫故而知新吧!
一個tableView上的某個cell(后面用cellA代替)上有一個scrollView,該scrollView上添加了幾個tableView。要求在cellA所在的section的sectionHeader滑動到頂部的時候cellA上的scrollView上的幾個tableView可以滑動,否則不能滑動。
1.需要底部的tableView能夠同時響應多個手勢(這樣在滑動子tableView時候,底部的tableView也能滑動)
2.在最開始的時候底部tableView能夠滑動,scrollView上的tableView不能滑動。
3.當cellA所在的section的sectionHeader滑動到頂部的時候,scrollView上的幾個tableView可以滑動。
4.當scrollView上的tableView在Y方向的偏移量為0的時候,scrollView上tableView不能滑動,底部的tableView能滑動。
1.監(jiān)聽底部tableView的偏移量,從而設置該tableView以及scrollView上幾個tableView是否能滑動
2.設置scrollView上幾個tableView是否能滑動
3.監(jiān)聽scrollView上幾個tableView的偏移量,從而通知底部tableView是否可滑動
4.接收通知,從而設置底部tableView以及scrollView上幾個tableView是否能滑動