細說UIScrollView上的Touch 事件

1 開篇

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

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

2 問題

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

3 UIScrollerView 原理

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

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

自己也總結了下,沒上面的這位易於理解。所以就直接引用了,多看幾遍發現還真是這麼回事。

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];  
  9.     

最後附上一個簡單版的demo 

本文出自 “技術成就夢想” 博客,請務必保留此出處http://285746555.blog.51cto.com/2966432/658383

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章