Is there a way to make the background of a UIView a gradient without subclassing it? I'd rather not use an image file to accomplish this either. It just seems obtuse to have to subclass UIView just to draw a gradient for the background.
Asked
Active
Viewed 4.0k times
4 Answers
33
You can use +[UIColor colorWithPatternImage:]
to produce a patterned background. Example (bring your own CGGradient):
// Allocate color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Allocate bitmap context
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, 320, 480, 8, 4 * 320, colorSpace, kCGImageAlphaNoneSkipFirst);
//allocate myGradient
CGFloat locationList[] = {0.0f, 1.0f};
CGFloat colorList[] = {0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
CGGradientRef myGradient = CGGradientCreateWithColorComponents(colorSpace, colorList, locationList, 2);
// Draw Gradient Here
CGContextDrawLinearGradient(bitmapContext, myGradient, CGPointMake(0.0f, 0.0f), CGPointMake(320.0f, 480.0f), 0);
// Create a CGImage from context
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
// Create a UIImage from CGImage
UIImage *uiImage = [UIImage imageWithCGImage:cgImage];
// Release the CGImage
CGImageRelease(cgImage);
// Release the bitmap context
CGContextRelease(bitmapContext);
// Release the color space
CGColorSpaceRelease(colorSpace);
// Create the patterned UIColor and set as background color
[targetView setBackgroundColor:[UIColor colorWithPatternImage:image]];
It will probably be simpler to just create a UIView
subclass though. It will use less memory as well.

andrewchan2022
- 4,953
- 45
- 48

rpetrich
- 32,196
- 6
- 66
- 89
-
there is a memory leak in line #2 where there is no chance to release the result of CGColorSpaceCreateDeviceRGB() – wangii Dec 06 '11 at 22:45
-
Good implementaion. One question though, will this works with the new retina display devices? (I saw that 320x480 is hard coded there) – chakrit Mar 30 '12 at 10:42
-
@chakrit, it will still work with retina devices, but only render the gradient at 1x resolution; depending on the gradient that may be sufficient. 320x480 is hard coded to make the sample simpler–would be better to use whatever the actual view size is. – rpetrich Apr 22 '12 at 04:29
-
@AlexanderPerechnev it is a `CGGradientRef` that you create using `CGGradientCreateWithColors`/`CGGradientCreateWithColorComponents` – rpetrich Dec 01 '13 at 04:38
29
You could do:
Swift >= 4.0:
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.red.cgColor, UIColor.white.cgColor]
view.layer.insertSublayer(gradient, at: 0)
Swift 3.0:
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.red().cgColor, UIColor.white().cgColor]
view.layer.insertSublayer(gradient, at: 0)
Swift <= 2.3:
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.redColor().CGColor, UIColor.whiteColor().CGColor]
view.layer.insertSublayer(gradient, atIndex: 0)
Objective-C:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[self.view.layer insertSublayer:gradient atIndex:0];
Make sure to add the QuartzCore framework to your project as well (at least for Objective-C)...
#import <QuartzCore/QuartzCore.h>

keji
- 5,947
- 3
- 31
- 47
-
-
when i use this code i'm getting error like Undefined symbols for architecture i386: "_OBJC_CLASS_$_CAGradientLayer", referenced from: – Vinoth Kumar Oct 04 '14 at 03:41
-
-
i wrote this "cellForRowAtIndexPath" ,so that i can display gradient view in each cell,and it works fine,now i face a problem,while i scroll up and down,the gradient color is coming darker and darker.how to solve this? – jithin Jan 26 '16 at 10:14
-
@jithin I would post a question with that code that you are using. I think that you are adding the layer each time and it is getting reused by the tableView thus making it a darker shade each time – keji Jan 27 '16 at 00:43
-
-
@jithin you can remove the sublayer -> http://stackoverflow.com/questions/2067578/removing-all-calayers-sublayers OR you can create a new cell each time – keji Jan 27 '16 at 04:15
-
-
@jithin sorry but I posted a bad link. I wouldn't remove all the layers. I would use this answer so you can guarantee you are removing the correct layer: http://stackoverflow.com/questions/2853568/tagging-calayers-in-iphone. Then I would also make sure that the number of sublayers is greater than 0; cause I think what my be happening is that you are removing an important sublayer or you are removing a sublayer from a layer that doesn't have any. – keji Jan 27 '16 at 09:31
-
@jithin if you could post this as a question or send your code to my email: me@kez.io I could take a look and help you with it. – keji Jan 27 '16 at 09:32
-
1
I agree with rpetrich, it would be cleaner to just do the UIView subclass. For an example of how to do this, see my response in this question. If you wanted, you could create a generic gradient UIView subclass and simply place that behind the views you want to have gradient backgrounds.

Community
- 1
- 1

Brad Larson
- 170,088
- 45
- 397
- 571
0
I change the adopted answer to my edition
+(void) setBlackGradientToView:(UIView*)targetView
{
CGRect frame = targetView.frame;
// Allocate color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//allocate myGradient
CGFloat locationList[] = {0.0f, 1.0f};
CGFloat colorList[] = {0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
CGGradientRef myGradient = CGGradientCreateWithColorComponents(colorSpace, colorList, locationList, 2);
// Allocate bitmap context
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, frame.size.width, frame.size.height, 8, 4 * frame.size.width, colorSpace, kCGImageAlphaPremultipliedLast);
//Draw Gradient Here
CGContextDrawLinearGradient(bitmapContext, myGradient, CGPointMake(0.0f, 0.0f), CGPointMake(0, frame.size.height), 0);
// Create a CGImage from context
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
// Create a UIImage from CGImage
UIImage *uiImage = [UIImage imageWithCGImage:cgImage];
// Release the CGImage
CGImageRelease(cgImage);
// Release the bitmap context
CGContextRelease(bitmapContext);
// Release the color space
CGColorSpaceRelease(colorSpace);
//Create the patterned UIColor and set as background color
[targetView setBackgroundColor:[UIColor colorWithPatternImage:uiImage]];
//return uiImage;
}

andrewchan2022
- 4,953
- 45
- 48