1. 程式人生 > >UIScrollView的作用原理,實現scrollView中touch事件作用子檢視

UIScrollView的作用原理,實現scrollView中touch事件作用子檢視

我們知道當多個檢視進行疊加的時候,touch事件是作用到最上面的檢視上,但是如果父檢視是UIScrollView,如果預設,可能touch子檢視會造成UIScrollView的滾動。

UIScrollView滾動的原因,可以看UIScrollView 原理

我在這裡簡單的描述一下,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。

#import <UIKit/UIKit.h>

 

@interface myScrollView : UIScrollView { 
}

 

@end

具體的實現:

#import "myScrollView.h"

 

#import "MyView.h"

 

@implementation myScrollView

 

- (id)initWithFrame:(CGRect)frame 

    self = [super initWithFrame:frame]; 
    if (self) { 
        [self setBackgroundColor:[UIColor redColor]]; 
        
        MyView *myView=[[MyView alloc] initWithFrame:CGRectMake(1, 3, 100, 200)]; 
        [self addSubview:myView]; 
        [myView release]; 
    } 
    return self; 
}

 

- (void)dealloc 

    [super dealloc]; 
}

 

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

    NSLog(@"使用者點選了scroll上的檢視%@,是否開始滾動scroll",view); 
    //返回yes 是不滾動 scroll 返回no 是滾動scroll 
    return YES; 

- (BOOL)touchesShouldCancelInContentView:(UIView *)view 

  
    NSLog(@"使用者點選的檢視 %@",view); 
   
    //NO scroll不可以滾動 YES scroll可以滾動 
    return NO; 

@end

重寫了- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view方法和- (BOOL)touchesShouldCancelInContentView:(UIView *)view方法。

其中(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view,是使用者點選黃色區域內,先觸發這個方法,當返回YES時,touch事件作用到黃色檢視上,當返回no時,紅色可以上下滾動。

(BOOL)touchesShouldCancelInContentView:(UIView *)view是傳送tracking前,先作用這個方法。

下面是點選黃的區域的日誌:

2011-06-02 10:19:42.469 scrollTouch[38255:207] 使用者點選了scroll上的檢視<MyView: 0x4e26f90; frame = (1 3; 100 200); layer = <CALayer: 0x4e270a0>>,是否開始滾動scroll 
2011-06-02 10:19:42.658 scrollTouch[38255:207] 使用者點選的檢視 <MyView: 0x4e26f90; frame = (1 3; 100 200); layer = <CALayer: 0x4e270a0>>

二、新增mySrollView到根檢視上:

- (void)viewDidLoad 

    [super viewDidLoad]; 

    myScrollView *view=[[myScrollView alloc] initWithFrame:CGRectMake(10, 9, 300, 400)]; 
    [view setUserInteractionEnabled:YES]; 
    [view setScrollEnabled:YES]; 

//NO 傳送滾動的通知 但是就算手指移動 scroll也不會動了 YES 傳送通知 scroll可以移動 
    [view setCanCancelContentTouches:YES]; 
    [view setBounces:NO]; 
    // NO 立即通知touchesShouldBegin:withEvent:inContentView 看是否滾動 scroll 
    [view setDelaysContentTouches:NO]; // 這句是關鍵,預設為YES,不設為NO則touchesShouldBegin:withEvent:inContentView:可能不被回撥
    [view setContentSize:CGSizeMake(300, 900)]; 
    [self.view addSubview:view]; 
    [view release]; 
}

三、MyView檢視的實現。

#import "MyView.h"

 

@implementation MyView

 

- (id)initWithFrame:(CGRect)frame 

    self = [super initWithFrame:frame]; 
    if (self) { 
        [self setBackgroundColor:[UIColor yellowColor]]; 
    } 
    return self; 
}

 

- (void)dealloc 

    [super dealloc]; 
}

 

@end