Ich Unterklasse UIScrollView und einige visuelle Elemente hinzufügen. An der Spitze sollte ein Farbverlauf von schwarz nach klar sein, und unten ist eine Maske, die nach unten ausläuft. Ich habe diese Ebenen hinzugefügt und sehe richtig aus, aber wenn ich scrolle, bleiben sie an den Koordinaten, in die ich sie eingefügt habe (in Bezug auf die Bildlaufansicht), anstatt am unteren und oberen Rand der Ansicht "fixiert" zu sein. Diese Bildlaufansicht scrollt nur vertikal. HierFixing CALayer oben und unten von UIScrollView
ist der Code für 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
Ich kenne eine Lösung für die oben nur eine separate Ansicht hinzufügen könnte, die einen Gradienten enthält, aber für den Boden Ich glaube, ich brauche zu verwenden eine Maske, damit es macht, was ich will (ganz unten in den Hintergrund einblenden). Der Hintergrund ist ein Bild, so dass ich nicht einfach zu weiß oder einer anderen Farbe verblassen kann, es muss zum Löschen verschwinden. Ich habe nach einer Methode gesucht, die aufgerufen wird, wenn die Bildlaufansicht verschoben wird und damit die Position der Maske ändert, aber ich habe noch nichts gefunden. Irgendwelche Vorschläge?
Ah, layoutSubviews war die Methode, die ich suchte. Vielen Dank! – Ned