I'm creating CGGradientRef
with CGGradientCreateWithColorComponents which is documented to support an alpha channel:
The number of items in this array should be the product of count and the number of components in the color space. For example, if the color space is an RGBA color space and you want to use two colors in the gradient (one for a starting location and another for an ending location), then you need to provide 8 values in components—red, green, blue, and alpha values for the first color, followed by red, green, blue, and alpha values for the second color.
Below is complete view implementation:
.h
@interface AlphaGrad : UIView
@end
.m
@implementation AlphaGrad
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
-(void) drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextClip(ctx);
CGGradientRef gradient = [self newGradientWithColors:[NSArray arrayWithObjects:[UIColor blackColor], [UIColor colorWithRed:0 green:0 blue:0 alpha:0.0f], nil]
locations:[NSArray arrayWithObjects:@0, @1, nil]];
CGContextDrawLinearGradient(ctx, gradient, CGPointMake(rect.origin.x, rect.origin.y),
CGPointMake(rect.origin.x, rect.origin.y+rect.size.height), kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
CGContextRestoreGState(ctx);
}
- (CGGradientRef)newGradientWithColors:(NSArray*)colorsArray locations:(NSArray*)locationsArray {
int count = [colorsArray count];
CGFloat* components = malloc(sizeof(CGFloat)*4*count);
CGFloat* locations = malloc(sizeof(CGFloat)*count);
for (int i = 0; i < count; ++i) {
UIColor* color = [colorsArray objectAtIndex:i];
NSNumber* location = (NSNumber*)[locationsArray objectAtIndex:i];
size_t n = CGColorGetNumberOfComponents(color.CGColor);
const CGFloat* rgba = CGColorGetComponents(color.CGColor);
if (n == 2) {
components[i*4] = rgba[0];
components[i*4+1] = rgba[0];
components[i*4+2] = rgba[0];
components[i*4+3] = rgba[1];
} else if (n == 4) {
components[i*4] = rgba[0];
components[i*4+1] = rgba[1];
components[i*4+2] = rgba[2];
components[i*4+3] = rgba[3];
}
locations[i] = [location floatValue];
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorSpaceRef space = CGBitmapContextGetColorSpace(context);
CGGradientRef gradient = CGGradientCreateWithColorComponents(space, components, locations, count);
free(components);
free(locations);
return gradient;
}
@end
The problem is that transparency seems not to be supported, transparent part is drown as white:
Is it possible to get transparency with CGGradientRef
to make a "lower" subview partially visible ?