Fantattitude
Fantattitude

Reputation: 1842

How to create a CGGradient for my UIView subclass?

Does anyone know how to create a CGGradient that will fill my view,
my current code is this and it fill the UIView with a red rectangle I want to have a gradient (from black to grey for instance) instead of the rect :

- (void)drawRect:(CGRect)rect {
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGRect r;
    r.origin.x=0.;
    r.origin.y=0.;
    r.size.width=rect.size.width;   
    r.size.height=rect.size.height; 
    CGContextSetRGBFillColor(context, 1., 0., 0., 1.);
    CGContextFillRect (context,r);  
}

Upvotes: 1

Views: 10400

Answers (3)

sebastian friedrich
sebastian friedrich

Reputation: 921

this is a subclass where you can chose the colors

.h file

#import <UIKit/UIKit.h>

@interface GradientView : UIView {
    CGGradientRef gradient;
}

@property(nonatomic, assign) CGGradientRef gradient;

- (id)initWithGradient:(CGGradientRef)gradient;
- (id)initWithColor:(UIColor*)top bottom:(UIColor*)bot;
- (void)setGradientWithColor:(UIColor*)top bottom:(UIColor*)bot;
- (void)getRGBA:(CGFloat*)buffer;

@end

.m file

#import "GradientView.h"

@implementation GradientView

@synthesize gradient;

- (id)initWithGradient:(CGGradientRef)grad {
    self = [super init];
    if(self){
        [self setGradient:grad];
    }
    return self;
}

- (id)initWithColor:(UIColor*)top bottom:(UIColor*)bot {
    self = [super init];
    if(self){
        [self setGradientWithColor:top bottom:bot];
    }
    return self;
}

- (void)setGradient:(CGGradientRef)g {
    if(gradient != NULL && g != gradient){
        CGGradientRelease(gradient);
    }
    if(g != gradient){
        CGGradientRetain(g);
    }
    gradient = g;
    [self setNeedsDisplay];
}

- (void)setGradientWithColor:(UIColor*)top bottom:(UIColor*)bot {
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
    CGFloat clr[8];
    [top getRGBA:clr];
    [bot getRGBA:clr+4] ;
    CGGradientRef grad = CGGradientCreateWithColorComponents(rgb, clr, NULL, sizeof(clr)/(sizeof(clr[0])*4));
    [self setGradient:grad];
    CGColorSpaceRelease(rgb);
    CGGradientRelease(grad);
}

- (void)getRGBA:(CGFloat*)buffer {
    CGColorRef clr = [self CGColor];
    NSInteger n = CGColorGetNumberOfComponents(clr);
    const CGFloat *colors = CGColorGetComponents(clr);
    // TODO: add other ColorSpaces support
    switch (n) {
        case 2:
            for(int i = 0; i<3; ++i){
                buffer[i] = colors[0];
            }
            buffer[3] = CGColorGetAlpha(clr);
            break;
        case 3:
            for(int i = 0; i<3; ++i){
                buffer[i] = colors[i];
            }
            buffer[3] = 1.0;
            break;

        case 4:
            for(int i = 0; i<4; ++i){
                buffer[i] = colors[i];
            }
            break;
        default:
            break;
    }
}

- (void)drawRect:(CGRect)rect {
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextDrawLinearGradient(c, gradient, CGPointMake(0, 0), CGPointMake(0, rect.size.height), 0);
}


- (void)dealloc {
    CGGradientRelease(gradient);
    [super dealloc];
}


@end

Upvotes: 3

Brad Larson
Brad Larson

Reputation: 170317

In my answer to this question, I provide code for drawing a gloss gradient within a UIView. The colors and drawing positions can be modified from that to form whatever linear gradient you need.

Upvotes: 3

Peter Hosey
Peter Hosey

Reputation: 96393

Use CGGradientCreateWithColorComponents or CGGradientCreateWithColors to create the gradient. (The latter takes CGColor objects.) Then, use CGContextDrawLinearGradient or CGContextDrawRadialGradient to draw it.

A linear gradient will extend infinitely in at least the two directions perpendicular to the line of the gradient. A radial gradient extends infinitely in every direction. To prevent the gradient from spilling outside your view, you'll probably need to add the view's bounds to the clipping path using CGContextClipToRect.

Upvotes: 2

Related Questions