UIScrollView的作用原理,实现scrollView传递touch事件给子视图【转】

来源:互联网 发布:淘宝网格子连衣裙 编辑:程序博客网 时间:2024/04/30 10:53

原文:http://blog.csdn.net/backapace/article/details/10897449

UIScrollView的工作原理,当手指touch的时候,UIScrollView会拦截Event,会等待一段时间,在这段时间内,如果没有手指没有移动,当时间结束时,UIScrollView会发送tracking events到子视图上。在时间结束前,手指发生了移动,那么UIScrollView就会进行移动,从而取笑发送tracking。

 

那么,UIScrollView的子类想要接受touch事件,就是用户点击UIScrollView上的视图时,要先处理视图上的touch,而不发生滚动。这时候就需要UIScrollView的子类重载touchesShouldBegin:withEvent:inContentView: ,从而决定自己是否接受子视图中的touch事件。

上面都是理论的知识,下面看一个简单的例子:

image

外面红色是一个UIScrollView黄色是在UIScrollView上添加的UIView。最后的效果是,当在黄色区域内touch时,touch事件会作用到UIView上,当touch红色区域时,整个视图上下滚动。下面是实现的过程。

一、创建工程,然后创建myScrollView,并且myScrollView继承自UIScrollView。

[plain] view plaincopy
  1. #import <UIKit/UIKit.h>  
  2. @interface myScrollView : UIScrollView  
  3. @end  
具体的实现:

[plain] view plaincopy
  1. #import "myScrollView.h"  
  2. #import "myView.h"  
  3.   
  4. @implementation myScrollView  
  5. - (id)initWithFrame:(CGRect)frame {  
  6.     self = [super initWithFrame:frame];  
  7.     if (self) {  
  8.         // Initialization code  
  9.         [self setBackgroundColor:[UIColor redColor]];  
  10.           
  11.         myView * aView = [[myView alloc] initWithFrame:CGRectMake(1, 3, 100, 200)];  
  12.         [self addSubview:aView];  
  13.         [aView release];  
  14.     }  
  15.     return self;  
  16. }  
  17.   
  18. - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {  
  19.     NSLog(@"用户触摸了scroll上的视图%@,是否开始滚动scroll", view);  
  20.     //返回yes - 将触摸事件传递给相应的subView; 返回no - 直接滚动scrollView,不传递触摸事件到subView  
  21.     return YES// NO;  
  22. }  
  23.   
  24. - (BOOL)touchesShouldCancelInContentView:(UIView *)view{  
  25.     NSLog(@"scrollView取消传递触摸事件到视图%@", view);      
  26.     //no - 不取消,touch事件由view处理,scrollView不滚动; yes - scrollView取消,touch事件由scrollView处理,可滚动  
  27.     return YES// NO;  
  28. }  
  29.   
  30. @end  

重写了方法

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view

- (BOOL)touchesShouldCancelInContentView:(UIView *)view。


(BOOL)touchesShouldBegin:withEvent:inContentView:

用户点击黄色区域时,先触发这个方法。

当返回YES时,touch事件作用到黄色视图上;

当返回no时,touch事件不传递到黄色视图,红色视图马上滚动(当然前提是scrollView的scrollEnabled字段为YES)。


(BOOL)touchesShouldCancelInContentView:

只有scrollView的canCancelContentTouches字段为YES 且 (BOOL)touchesShouldBegin:withEvent:inContentView:返回YES时,这个方法才会被调用。

调用前,由于(BOOL)touchesShouldBegin:withEvent:inContentView:返回YES,scrollView上对应的view会接收到touch事件,因此方法(BOOL)touchesShouldCancelInContentView:被调用前,view可以已经触发了touchesBegan:withEvent:方法甚至是touchesMoved:withEvent:方法,至于view最后会调用touchesEnden:withEvent:还是touchesCanceled:withEvent:取决于(BOOL)touchesShouldCancelInContentView:的返回值

scrollView发送tracking前,调用这个方法。

返回YES时,若scrollView的canCancelContentTouches字段为YES,view会马上调用touchesCanceled:withEvent:,scrollView进行tracking以滚动。

返回NO时,scrollView不进行tracking,也不滚动,touch事件交由view处理。


二、添加mySrollView到根视图上

[plain] view plaincopy
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view, typically from a nib.      
  5.     [self layoutCstmView];  
  6. }  
  7.   
  8. - (void)layoutCstmView  
  9. {  
  10.     myScrollView * scrollView = [[myScrollView alloc] initWithFrame:CGRectMake(10, 9, 300, 400)];  
  11.     [scrollView setUserInteractionEnabled:YES];  
  12.     [scrollView setScrollEnabled:YES];  
  13.       
  14.     //NO - 设置scrollView不能取消传递touch事件,此时就算手指若在subView上滑动,scrollView不滚动; YES - 设置scrollView可取消传递touch事件  
  15.     [scrollView setCanCancelContentTouches:YES];  
  16.     [scrollView setBounces:NO];  
  17.       
  18.     //NO - 立即通知touchesShouldBegin:withEvent:inContentView  
  19.     [scrollView setDelaysContentTouches:NO];  
  20.     [scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, 900)];  
  21.       
  22.     [self.view addSubview:scrollView];  
  23.     [scrollView release];  
  24. }  

三、MyView视图的实现

[plain] view plaincopy
  1. #import "myView.h"  
  2.   
  3. @implementation myView  
  4.   
  5. - (id)initWithFrame:(CGRect)frame  
  6. {  
  7.     self = [super initWithFrame:frame];  
  8.     if (self) {  
  9.         // Initialization code  
  10.         self.backgroundColor = [UIColor yellowColor];  
  11.     }  
  12.     return self;  
  13. }  
  14.   
  15. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  
  16.     printf("myView touchesBegan \n");  
  17.     self.backgroundColor = [UIColor grayColor];  
  18. }  
  19.   
  20. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {  
  21.     printf("myView touchesMoved \n");  
  22. }  
  23.   
  24. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
  25.     printf("myView touchesEnded \n");  
  26. }  
  27.   
  28. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {  
  29.     printf("myView touchesCancelled \n");  
  30.     self.backgroundColor = [UIColor yellowColor];  
  31. }  
  32.      
  33. @end  
0 0
原创粉丝点击