2010-12-16 205 views
1

我是UIScrollView的子類,並添加了一些視覺元素。在頂部,應該有一個從黑色到清晰的漸變,底部有一個朝向底部漸變的面罩。我添加了這些圖層並且看起來正確,但是當我滾動時,它們停留在我將它們放入的座標中(相對於滾動視圖),而不是「固定」到視圖的底部和頂部。此滾動視圖只能垂直滾動。修復CALayer在UIScrollView的頂部和底部

這裏是SettingsScrollView.m代碼:

#import "SettingsScrollView.h" 
#import <QuartzCore/QuartzCore.h> 

#define SHADOW_HEIGHT 20.0 
#define SHADOW_INVERSE_HEIGHT 10.0 
#define SHADOW_RATIO (SHADOW_INVERSE_HEIGHT/SHADOW_HEIGHT) 

@implementation SettingsScrollView 


- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 

    [self setUpShadow]; 

    return self; 
} 

- (CAGradientLayer *)shadowAsInverse:(BOOL)inverse 
{ 
    CAGradientLayer *newShadow = [[[CAGradientLayer alloc] init] autorelease]; 
    CGRect newShadowFrame = CGRectMake(0, 0, self.frame.size.width, inverse ? SHADOW_INVERSE_HEIGHT : SHADOW_HEIGHT); 
    newShadow.frame = newShadowFrame; 
    CGColorRef darkColor =[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:inverse ? (SHADOW_INVERSE_HEIGHT/SHADOW_HEIGHT) * 0.5 : 0.5].CGColor; 
    CGColorRef lightColor = [self.backgroundColor colorWithAlphaComponent:0.0].CGColor; 

    newShadow.colors = [NSArray arrayWithObjects: (id)(inverse ? lightColor : darkColor), (id)(inverse ? darkColor : lightColor), nil]; 
    return newShadow; 
} 

- (CAGradientLayer *)gradientMask 
{ 
    CAGradientLayer *mask = [[[CAGradientLayer alloc] init] autorelease]; 
    CGRect maskFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 
    mask.frame = maskFrame; 
    CGColorRef darkColor =[UIColor clearColor].CGColor; 
    CGColorRef lightColor =[UIColor blackColor].CGColor; 

    mask.colors = [NSArray arrayWithObjects: (id)lightColor, (id)lightColor, (id)darkColor, nil]; 
    mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.9], [NSNumber numberWithFloat:1.0], nil]; 
    return mask; 
} 

- (void)setUpShadow 
{ 
    CAGradientLayer *topShadowLayer = [self shadowAsInverse:NO]; 
    CAGradientLayer *bottomShadowLayer = [self gradientMask]; 

    [self.layer insertSublayer:topShadowLayer atIndex:0]; 

    [self.layer setMask:bottomShadowLayer]; 

    [CATransaction begin]; 
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 

    CGRect topShadowLayerFrame = topShadowLayer.frame; 
    topShadowLayerFrame.size.width = self.frame.size.width; 
    topShadowLayerFrame.origin.y = 0; 
    topShadowLayer.frame = topShadowLayerFrame; 

    CGRect bottomShadowLayerFrame = bottomShadowLayer.frame; 
    bottomShadowLayerFrame.size.width = self.frame.size.width; 
    bottomShadowLayerFrame.origin.y = self.frame.size.height - bottomShadowLayer.frame.size.height; 
    bottomShadowLayer.frame = bottomShadowLayerFrame; 

    [CATransaction commit]; 
} 

@end 

我知道最上面的一個解決方案可能僅僅是添加包含梯度的獨立看法,但對於底部,我相信我需要使用一個面具讓它做我想做的事(淡入底部的背景)。背景是一張圖片,所以我不能只是褪色成白色或其他顏色,它需要淡入淡出。我一直在尋找一種方法,當滾動視圖移動並使用它來改變掩碼的位置時被調用,但我還沒有找到任何東西。有什麼建議麼?

回答

0

你可以通過在UIScrollView上覆蓋-layoutSubviews來完成這個任務,當邊界改變時調用它。

我見過的看法是這樣的另一項技術是不是從視圖中,子類CALayer做這一層的管理,使用你的子類作爲滾動視圖的圖層,然後在圖層的-layoutSublayers,做同樣的工作當它移動時。我提到後一種技術,因爲層管理其子層與直接管理其子層子層的視圖似乎更自然。

+0

啊,layoutSubviews是我正在尋找的方法。謝謝! – Ned 2010-12-16 16:08:03