How to fill a path with gradient in drawRect:?
38,890
I would clip to the path you want to fill, and use CGContextDrawLinearGradient. Here is a simple implementation of drawRect: as an example:
- (void) drawRect:(CGRect)rect
{
// Create a gradient from white to red
CGFloat colors [] = {
1.0, 1.0, 1.0, 1.0,
1.0, 0.0, 0.0, 1.0
};
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextClip(context);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextDrawPath(context, kCGPathStroke);
}
Author by
Derrick
Updated on July 09, 2022Comments
-
Derrick almost 2 years
filling a path with a solid color is easy enough:
CGPoint aPoint; for (id pointValue in points) { aPoint = [pointValue CGPointValue]; CGContextAddLineToPoint(context, aPoint.x, aPoint.y); } [[UIColor redColor] setFill]; [[UIColor blackColor] setStroke]; CGContextDrawPath(context, kCGPathFillStroke);
I'd like to draw a gradient instead of solid red, but I am having trouble. I've tried the code listed in the Question/Answer: Gradients on UIView and UILabels On iPhone
which is:
CAGradientLayer *gradient = [CAGradientLayer layer]; [gradient setFrame:rect]; [gradient setColors:[NSArray arrayWithObjects:(id)[[UIColor blueColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil]]; [[self layer] setMasksToBounds:YES]; [[self layer] insertSublayer:gradient atIndex:0];
However, this paints the entire view that this is in with the gradient, covering up my original path.
-
Derrick almost 14 yearsIf I could give you an awesome badge I would! Do you know of any tutorials on the CGContextSaveGState and stuff? Because the apple class reference is kind of thin.
-
Nico almost 14 yearsDerrick: The Quartz 2D Programming Guide covers that, along with everything else: developer.apple.com/mac/library/documentation/GraphicsImaging/…
-
Doron almost 14 yearsAfter using your example code, my shadow has disappeared. I've tried relocating the shadow line ("CGContextSetShadow(context, CGSizeMake(5.0, -5.0), 4);") before the gstate save, after it, befroe the gstate restore, after it, before and after the clipping - nothing helped.
-
daveMac over 11 years@Doron Once you fill or stroke (I believe even clip) a path, that path is essentially nil and subsequent fills or strokes do nothing. You need to copy the path first.
-
ArtOfWarfare over 11 years@Doron - Expanding on what daveMac said, I found I had to call
CGContextAddPath
(with my copied path from before) between my calls to FillPath and Clip. -
Victor Engel about 11 yearsI just found out about CGPathCreateCopyByStrokingPath, availabel in iOS 5 and later that creates a CGPath around an existing path. This should simplify drawing the gradient you're after.
-
Alex Zavatone almost 3 yearsUpdated location of Quartz 2D Programming Guide - developer.apple.com/library/archive/documentation/…