細說UIScrollView上的Touch 事件

1 開篇ide

最近在項目中遇到一個 需求就是在一個能夠左右撥動的頁面上,添加一些交互功能,好比說點擊某個頁面會有文字變化,圖片變換,最後有比較特殊的需求是作個像slider功能的能夠拖動的按鈕,而且有吸附功能,即當滑動中止在兩個圖標間的時候,能夠滑向離本身比較近的圖標。函數

(PS:本人是新手,哈哈,高手就全當路過吧),一看到的時候覺的沒什麼問題,很簡單的不就是一個scrollview+touch 事件就能搞定麼,但是作着就出問題了。spa

2 問題xml

發現放在scrollview上的view 都不能響應touch 事件,想了很久不得其解,應該沒什麼東西覆蓋在view 上,怎麼點擊就是沒反應呢?網上轉了一圈,真實收穫很多,特別是一篇UIScrollerView 原理詳解,更使我恍然大悟,書到用時方恨少啊 。事件

3 UIScrollerView 原理圖片

其實這個原理道理網上已經講的很明白,我就引用下上面那位高手的原文吧:it

UIScrollView的工做原理,當手指touch的時候,UIScrollView會攔截Event,會等待一段時間,在這段時間內,若是沒有手指 沒有移動,當時間結束時,UIScrollView會發送tracking events到子視圖上。在時間結束前,手指發生了移動,那麼UIScrollView就會進行移動,從而取笑發送tracking。event

本身也總結了下,沒上面的這位易於理解。因此就直接引用了,多看幾遍發現還真是這麼回事。class

4 問題的解決思路原理

通常是兩個思路,一個是經過定製一個scrollerview,並重寫他的touch 方法。

 

  1. - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{ 
  2. if(!self.dragging) 
  3. [[selfnextResponder]touchesBegan:toucheswithEvent:event]; 
  4. [supertouchesBegan:toucheswithEvent:event]; 
  5. //NSLog(@"MyScrollView touch Began"); 
  6.  
  7. - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event 
  8. if(!self.dragging) 
  9. [[selfnextResponder]touchesEnded:toucheswithEvent:event]; 
  10. [supertouchesEnded:toucheswithEvent:event]; 

第二個是經過響應鏈將事件傳遞給下一個響應者去實現,即將俯視圖的事件傳遞給子視圖去處理

目前大體就這兩個方法來處理

5一些準備

下面這個函數的功能是判斷是否能夠把touch 事件傳遞給子視圖,即在他上面的視圖。當返回是yes 的時候就表示能夠,就當點擊子視圖view 的時候中止響應scroll事件,改而響應子視圖的touch 事件,當爲no 時則拒絕子視圖響應,執行父視圖的touch 事件,下面的代碼時實現了當子視圖時按鈕的時候就響應其對應的功能,子不少時候仍是很管用的。

  1. //父視圖是否能夠將消息傳遞給子視圖,yes是將事件傳遞給子視圖,則不滾動,no是不傳遞則繼續滾動 
  2. - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view 
  3.     if ([view isKindOfClass:[UIButton class]])  
  4.     { 
  5.         return YES; 
  6.     } 
  7.     else 
  8.     { 
  9.         return NO; 
  10.     } 
  11.      

 

     setDelaysContentTouches  這個函數主要時判斷是否延遲執行tracking 通常狀況下是yes  即會延遲執行,就是先等待一下子看scrollview 是否有touch 事件發生,若是沒有則轉而執行子視圖的 的touch 事件。
  1. //yes 則發送一個能夠touchesCancelled:withEvent:  而後把這個事件看成一次滾動賴實現 
  2.     [baseScrollView setCanCancelContentTouches:YES]; 
  3.      
  4.     //滾動的時候是否能夠除邊界,即到邊界的時候是否能夠多看到一點內容 
  5.     [baseScrollView setBounces:NO]; 
  6.      
  7.     // 當值是NO 當即調用 touchesShouldBegin:withEvent:inContentView 看是否滾動 scroll 
  8.     [baseScrollView setDelaysContentTouches:NO];  
相關文章
相關標籤/搜索