细说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];  
相关文章
相关标签/搜索