In some particular circumstances, we want to use a gradient background view. As far as my knowledge can reach, there are three different ways to implement a gradient background: CAGradientLayer, CGGradient and CoreImage.
First, Let’s have a look at the result.
To define the gradient colour, we have at least four properties:
@property (nonatomic) CGPoint inputPoint0;
@property (nonatomic) CGPoint inputPoint1;
@property (nonatomic) UIColor *inputColor0;
@property (nonatomic) UIColor *inputColor1;
The two CGPoint properties define where the gradient colour begins and ends. They are defined in a unit coordinate space where (0, 0) at the top left and (1, 1) at the bottom right. The two UIColor properties define the start colour and the end colour.
1. CAGradientLayer
We are not going to discuss the details of how to use CAGradientLayer. There is a good article talking about it: http://www.cnblogs.com/YouXianMing/p/3793913.html.
CAGradientLayer *layer = [CAGradientLayer new];
layer.colors = @[(__bridge id)_inputColor0.CGColor, (__bridge id)_inputColor1.CGColor];
layer.startPoint = _inputPoint0;
layer.endPoint = _inputPoint1;
layer.frame = self.bounds;
[self.layeraddSublayer:layer];
2. CGGradientRef
About Core Graphics and Core Image, please refer here, a very very good article:
http://www.techotopia.com/index.php/An_iOS_7_Graphics_Tutorial_using_Core_Graphics_and_Core_Image
Note that CAGradientLayer is using unit coordinate space while Core Graphics and Core Image are not. More Interestingly, Core Graphics’ coordinate space where (0, 0) starts at the top left is different from Core Image’s where (0, 0) starts at bottom left.
The following code is called in drawRect:.
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = {0,1};
NSArray *colors = @[(__bridge id)_inputColor0.CGColor, (__bridge id)_inputColor1.CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef) colors, locations);
CGColorSpaceRelease(colorSpace);
CGPoint startPoint = (CGPoint){rect.size.width * _inputPoint0.x, rect.size.height * _inputPoint0.y};
CGPoint endPoint = (CGPoint){rect.size.width * _inputPoint1.x, rect.size.height * _inputPoint1.y};
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
UIGraphicsPopContext();
3. Core Image
The following code is called in drawRect:.
CIFilter *ciFilter = [CIFilter filterWithName:@"CILinearGradient"];
CIVector *vector0 = [CIVector vectorWithX:rect.size.width * _inputPoint0.x Y:rect.size.height * (1 - _inputPoint0.y)];
CIVector *vector1 = [CIVector vectorWithX:rect.size.width * _inputPoint1.x Y:rect.size.height * (1 - _inputPoint1.y)];
[ciFilter setValue:vector0 forKey:@"inputPoint0"];
[ciFilter setValue:vector1 forKey:@"inputPoint1"];
[ciFilter setValue:[CIColor colorWithCGColor:_inputColor0.CGColor] forKey:@"inputColor0"];
[ciFilter setValue:[CIColor colorWithCGColor:_inputColor1.CGColor] forKey:@"inputColor1"];
CIImage *ciImage = ciFilter.outputImage;
CIContext *con = [CIContext contextWithOptions:nil];
CGImageRef resultCGImage = [con createCGImage:ciImage
fromRect:rect];
UIImage *resultUIImage = [UIImage imageWithCGImage:resultCGImage];
CGImageRelease(resultCGImage);
[resultUIImage drawInRect:rect];
Sample code can be found here: https://github.com/RungeZhai/LGGradientBackgroundView