How to fill UIBezierPath with a gradient?

I drew a graph using UIBezierPath. I can fill the area under the graph with solid color, but I want to fill the area under the graph with a gradient, not a solid color. But I'm not sure how to make the gradient apply only to the graph, and not to the whole view, I read a few questions, but did not find anything applicable.

enter image description here

This is the main graph drawing code:

// Draw the graph UIBezierPath *barGraph = [UIBezierPath bezierPath]; barGraph.lineWidth = 1.0f; [blueColor setStroke]; TCDataPoint *dataPoint = self.testData[0]; CGFloat x = [self convertTimeToXPoint:dataPoint.time]; CGFloat y = [self convertDataToYPoint:dataPoint.dataUsage]; CGPoint plotPoint = CGPointMake(x,y); [barGraph moveToPoint:plotPoint]; for (int ii = 1; ii < [self.testData count]; ++ii) { dataPoint = self.testData[ii]; x = [self convertTimeToXPoint:dataPoint.time]; y = [self convertDataToYPoint:dataPoint.dataUsage]; plotPoint = CGPointMake(x, y); [barGraph addLineToPoint:plotPoint]; } [barGraph stroke]; 

I am trying to fill out a graph by experimenting with the code as shown below, but to be honest, I'm not sure if I am doing this despite various tutorials and documentation:

 [barGraph closePath]; CGFloat colors [] = { 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2); CGColorSpaceRelease(baseSpace); CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), self.topY); CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), self.bottomY); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextClip(context); CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); CGGradientRelease(gradient); 
+7
ios uibezierpath
source share
1 answer

The easiest approach is to use the original bezier-free path to help you create a mask and apply this mask to the gradient layer. Now overlay the graph layer on top of the gradient layer.

So, for example, create a CAShapeLayer, close the path of the bezier of the graph, set its path as the path of the form layer and fill it with black. Now you have a mask, which is the shape of the area under the graph. Now make CAGradientLayer and make CAShapeLayer your mask . Before that, place the actual schedule.

So for example ( EDITED ):

enter image description here

Here is the code I used to create this drawing (my bezier path is very simple, there are only four points connected by three lines, but you can clearly see that the area below it is a gradient):

 CAShapeLayer* shape = [[CAShapeLayer alloc] init]; shape.frame = self.graph.bounds; CGFloat h = shape.frame.size.height; CGFloat w = shape.frame.size.width; NSArray* points = @[ [NSValue valueWithCGPoint:CGPointMake(0,h-50)], [NSValue valueWithCGPoint:CGPointMake(70,h-100)], [NSValue valueWithCGPoint:CGPointMake(140,h-75)], [NSValue valueWithCGPoint:CGPointMake(w,h-150)], ]; UIBezierPath* p = [UIBezierPath new]; [p moveToPoint:[points[0] CGPointValue]]; for (NSInteger i = 1; i < points.count; i++) [p addLineToPoint:[points[i] CGPointValue]]; shape.path = p.CGPath; shape.strokeColor = [UIColor blackColor].CGColor; shape.lineWidth = 2; shape.fillColor = nil; CAGradientLayer* grad = [[CAGradientLayer alloc] init]; grad.frame = self.graph.bounds; grad.colors = @[(id)[UIColor blueColor].CGColor, (id)[UIColor yellowColor].CGColor]; CAShapeLayer* mask = [[CAShapeLayer alloc] init]; mask.frame = self.graph.bounds; [p addLineToPoint:CGPointMake(w,h)]; [p addLineToPoint:CGPointMake(0,h)]; [p closePath]; mask.path = p.CGPath; mask.fillColor = [UIColor blackColor].CGColor; grad.mask = mask; [self.graph.layer addSublayer:grad]; [self.graph.layer addSublayer:shape]; 
+9
source share

All Articles