Draw gradient along a curved UIBezierPath Draw gradient along a curved UIBezierPath objective-c objective-c

Draw gradient along a curved UIBezierPath


The trick is to use the stroke path of the line (CGContextReplacePathWithStrokedPath) and clip it (CGContextClip) to restrict the gradient to the path:

// Create a gradient from white to redCGFloat 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;CGContextSetLineWidth(context, mapRect.size.height/700);CGContextSetLineJoin(context, kCGLineJoinRound);CGContextSetLineCap(context, kCGLineCapRound);CGContextAddPath(context, [self pathForOverlayForMapRect:mapRect].CGPath);CGContextReplacePathWithStrokedPath(context);CGContextClip(context);[self updateTouchablePathForMapRect:mapRect];// Define the start and end points for the gradient// This determines the direction in which the gradient is drawnCGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);CGGradientRelease(gradient), gradient = NULL;


In Swift 3 this can be achieved using the code below. This example is for a straight line but the same principles should apply.

    let startPoint = CGPoint(x:100, y:100)    let endPoint = CGPoint(x: 300, y:400)    let context = UIGraphicsGetCurrentContext()!    context.setStrokeColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0);    // create a line    context.move(to: startPoint)    context.addLine(to: endPoint)    context.setLineWidth(4)    // use the line created above as a clipping mask    context.replacePathWithStrokedPath()    context.clip()    // create a gradient    let locations: [CGFloat] = [ 0.0, 0.5 ]    let colors = [UIColor.green.cgColor,                  UIColor.white.cgColor]    let colorspace = CGColorSpaceCreateDeviceRGB()    let gradient = CGGradient(colorsSpace: colorspace,                              colors: colors as CFArray, locations: locations)    let gradientStartPoint = CGPoint(x: rect.midX, y: rect.minY)    let gradientEndPoint = CGPoint(x: rect.midX, y: rect.maxY)    context.drawLinearGradient(gradient!,                                start: gradientStartPoint, end: gradientEndPoint,                                options: .drawsBeforeStartLocation)    UIGraphicsEndImageContext()