2010-12-16 7 views
1

私はUIScrollViewをサブクラス化し、いくつかの視覚的要素を追加しています。上部には黒から明瞭なグラデーションがあり、下にはマスクが下に向かってフェードアウトしています。私はこれらのレイヤーを追加して見ていますが、スクロールすると、ビューの下部と上部に「固定」されるのではなく、スクロールビューに関してそれらを配置する座標にとどまります。このスクロールビューは垂直方向にのみスクロールします。ここでUIScrollViewの上と下のCALayerを固定する

は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 

私はトップのための1つの解決策は、単に勾配を含む別のビューを追加することができ知っているが、下のために私が使用する必要があると考えていますそれが私が望むことをするためのマスク(最下部の背景にフェードアウト)。バックグラウンドはイメージなので、白や他の色にフェードするだけでは消えることはできません。消えるまで消す必要があります。私はスクロールビューが移動され、マスクの位置を変更するためにそれを使用するときに呼び出されるメソッドを探していますが、まだ何も見つかりませんでした。助言がありますか?

答えて

0

UIScrollViewの-layoutSubviewsをオーバーライドすることで、これを実現できます。これは、境界が変更されたときに呼び出されます。

このようなビューで見たもう1つの手法は、ビューからこのレイヤー管理を行う代わりに、サブクラスCALayerを使用し、サブクラスをスクロールビューのレイヤーとして使用し、レイヤー-layoutSublayersで同じ作業を行いますそれが動き回るとき。レイヤーがそのサブレイヤーを管理しているのに対して、レイヤーがサブレイヤーを直接管理しているビューに対していくらか自然なように思えるので、この後者の手法について言及します。

+0

ああ、layoutSubviewsは私が探していた方法でした。ありがとう! – Ned

関連する問題