some_id
some_id

Reputation: 29896

CGGradient with 3 colors

How does one draw a CGGradient with 3 colors?

I have an array like so:

CFArrayRef colors = (__bridge CFArrayRef) [NSArray arrayWithObjects:(id)lightGradientColor.CGColor,
                                           (id)darkGradientColor.CGColor, (id)lightGradientColor.CGColor,
                                           nil];

but I dont see the dark color in the middle with light on top and bottom sections, but rather just light on top, with dark until the bottom.

Upvotes: 1

Views: 2001

Answers (2)

Johnny Rockex
Johnny Rockex

Reputation: 4196

Pass multiple colours using CGGradient instead of CAGardientLayer for smoother results:

A. Create a custom UIView class with an @property NSArray * colours in the header. In the implementation file, paste the following drawRect method.

-(void)drawRect:(CGRect)rect {

    //1. create vars
    float increment = 1.0f / (colours.count-1);
    CGFloat * locations = (CGFloat *)malloc((int)colours.count*sizeof(CGFloat));
    CFMutableArrayRef mref = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);

    //2. go through the colours, creating cgColors and locations
    for (int n = 0; n < colours.count; n++){
        CFArrayAppendValue(mref, (id)[colours[n] CGColor]);
        locations[n]=(n*increment);
    }

    //3. create gradient
    CGContextRef ref = UIGraphicsGetCurrentContext();
    CGColorSpaceRef spaceRef = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradientRef = CGGradientCreateWithColors(spaceRef, mref, locations);
    CGContextDrawLinearGradient(ref, gradientRef, CGPointMake(0.0, 0.0), CGPointMake(0.0, self.frame.size.height), kCGGradientDrawsAfterEndLocation);
    CGColorSpaceRelease(spaceRef);
    CGGradientRelease(gradientRef);
}

B. In the viewController you want to use the custom class, initialise it, set the frame and its colours. It works for anything more than one colour, and in this case runs from top to bottom.

Background * bg = [Background new];
[bg setFrame:self.view.bounds];
[bg setColours:@[[UIColor blueColor],[UIColor purpleColor]]];
[self.view addSubview:bg];

It's a smoother gradient than using the CAGradientLayer, and more noticeable if you drop the alpha on a colour:

CGGradient CAGradientLayer

Upvotes: 0

justin
justin

Reputation: 104698

Have you tried specifying/verifying the locations of your colors? The range is [0...1]:

const CGFloat locations[3] = {0.0, 0.5, 1.0};
CGGradientRef grad = CGGradientCreateWithColors(colorspace, colors, locations);

note: The locations above should be the same as passing 0 for the locations parameter.

Upvotes: 3

Related Questions