iPhone Development – Gradient background UIViews

Here’s a neat little tip I’ve found can spruce up your applications easily. It’s very easy to create a UIView with a solid background colour, but in our new rainbow coloured Web 2.0 shiny iPhone world, gradients are called for. You could of course create a gradient image and set the background image of the view, but this has several drawbacks:

  • For every different sized view, you either need to re-cut the gradient image or scale it.
  • It is a waste of space in your application, plus gradient images are often quite big files.
  • You need an image for each colour.
  • It is relatively expensive to load and render an image as a background for a view.

However using a bit of trickery, you can create a general GradientView class which extends UIView and overrides drawRect to achieve a gradient background. So I present GradientView:

//
//  GradientView.m
//  evilrockhopper
//
//  Created by Daniel Wichett on 10/12/2009.
//
//  Extension of UIView to show a gradient, generally used as a background on other views.
//  Mirrored indicates a gradient that is colour1 -> colour2 -> colour1. Non-mirrored simply goes from colour1 -> colour2.

#import "GradientView.h"

@implementation GradientView

@synthesize mirrored;

- (void)drawRect:(CGRect)rect
 {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
	
    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t numLocations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };

    //Two colour components, the start and end colour both set to opaque.
    CGFloat components[8] = { startRed, startGreen, startBlue, 1.0, endRed, endGreen, endBlue, 1.0 };
	
    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, numLocations);
	
    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds)/2.0);
    CGPoint bottomCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
	
    if (!mirrored)
    {
        // draw a gradient from top to bottom centred.
        CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, bottomCenter, 0);
    }
    else
    {
        // draw a gradient from top to middle, then reverse the colours and draw from middle to bottom.
        CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
        CGFloat components2[8] = { endRed, endGreen, endBlue, 1.0, startRed, startGreen, startBlue, 1.0 };
        CGGradientRelease(glossGradient);
        glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components2, locations, num_locations);
        CGContextDrawLinearGradient(currentContext, glossGradient, midCenter, bottomCenter, 0);		
    }
	
    // Release our CG objects.
    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace); 
}

// Set colours as component RGB.
- (void) setColours:(float) _startRed:(float) _startGreen:(float) _startBlue:(float) _endRed:(float) _endGreen:(float)_endBlue
{
	startRed = _startRed;
	startGreen = _startGreen;
	startBlue = _startBlue;
	
	endRed = _endRed;
	endGreen = _endGreen;
	endBlue = _endBlue;
}

// Set colours as CGColorRefs.
- (void) setColoursWithCGColors:(CGColorRef)color1:(CGColorRef)color2
{
	const CGFloat *startComponents = CGColorGetComponents(color1);
	const CGFloat *endComponents = CGColorGetComponents(color2);
    
	[self setColours:startComponents[0]:startComponents[1]:startComponents[2]:endComponents[0]:endComponents[1]:endComponents[2]];
}

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

@end

And the header file GradientView.h as so:

//
//  GradientView.h
//  evilrockhopper
//
//  Created by Daniel Wichett on 10/12/2009.
//

#import <UIKit/UIKit.h>

@interface GradientView : UIView 
{
    float startRed;
    float startGreen;
    float startBlue;

    float endRed;
    float endGreen;
    float endBlue;
	
    BOOL mirrored;
}

@property (nonatomic) BOOL mirrored;

- (void) setColoursWithCGColors:(CGColorRef)color1:(CGColorRef)color2;
- (void) setColours:(float) startRed:(float) startGreen:(float) startBlue:(float) endRed:(float) endGreen:(float)endBlue;

@end

So an example usage could be:

    GradientView *redToBlack = [[GradientView alloc] initWithFrame:CGRectMake(0,0,320,50)];
    [gradientBg setColoursWithCGColors:[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0].CGColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0].CGColor];

This creates a vertical gradient from red to black. If you wanted it to go from red to black to red, you can just set redToBlack.mirrored = YES.

It currently ignores the alpha value of the colours passed in, this would be trivial to add of course if required. If you want to experiment with other types of gradients, read the documentation for CGGradientCreateWithColorComponents. Feel free to use the code above, you can download the source by clicking on the menu in the top right of each code snippet.

2 responses to “iPhone Development – Gradient background UIViews”

  1. […] original post here: iPhone Development – Gradient background UIViews background, called-for-, course-create, […]

  2. Alexander6 says:

    Need cheap generic VIAGRA?…

Leave a Reply

Your email address will not be published. Required fields are marked *