¿Cómo llenar un UIBezierPath con un degradado?

Dibujé un gráfico usando UIBezierPath. Puedo llenar el área debajo del gráfico con un color sólido, pero quiero llenar el área debajo del gráfico con un degradado en lugar de con un color sólido. Pero no estoy seguro de cómo hacer que el degradado se aplique solo al gráfico y no a toda la vista, he leído algunas preguntas pero no he encontrado nada aplicable.

enter image description here

Este es el código de dibujo gráfico principal:

// 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]; 

He estado tratando de completar el gráfico experimentando con código como el siguiente, pero para ser honesto, no estoy 100% seguro de lo que estoy haciendo a pesar de pasar por varios tutoriales y documentación:

 [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); 

    El enfoque más fácil es utilizar el gráfico original de la ruta bezier para ayudarlo a construir una máscara e imponer esta máscara en una capa de degradado. Ahora impone la capa de gráfico en la parte superior de la capa de degradado.

    Entonces, por ejemplo, haga un CAShapeLayer, cierre el gráfico de la ruta de bezier, establezca su ruta como la ruta de la capa de forma y llénela de negro. Ahora tiene una máscara que tiene la forma del área debajo del gráfico. Ahora haga un CAGradientLayer y convierta CAShapeLayer en su mask . Delante de eso, coloca el gráfico real.

    Entonces, por ejemplo ( EDITADO ):

    enter image description here

    Aquí está el código que utilicé para crear ese dibujo (mi camino bezier es muy simple, solo cuatro puntos unidos por tres líneas, pero se puede ver claramente que el área debajo de él es un degradado):

     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];