How to fill a bezier path with gradient color

To answer this question of yours,

I have a UIBezierPath inside my custom UIView draw(_ rect: CGRect) function. I would like to fill the path with a gradient color.

Lets say you have an oval path,

let path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100))

To create a gradient,

let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.colors = [UIColor.magenta.cgColor, UIColor.cyan.cgColor]

We need a mask layer for gradient,

let shapeMask = CAShapeLayer()
shapeMask.path = path.cgPath

Now set this shapeLayer as mask of gradient layer and add it to view's layer as subLayer

gradient.mask = shapeMask
yourCustomView.layer.addSublayer(gradient)

Update Create a base layer with stroke and add before creating gradient layer.

let shape = CAShapeLayer()
shape.path = path.cgPath
shape.lineWidth = 2.0
shape.strokeColor = UIColor.black.cgColor
self.view.layer.addSublayer(shape)

let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.colors = [UIColor.magenta.cgColor, UIColor.cyan.cgColor]

let shapeMask = CAShapeLayer()
shapeMask.path = path.cgPath
gradient.mask = shapeMask

self.view.layer.addSublayer(gradient)

You can do this directly in Core Graphics without using CALayer classes. Use bezierPath.addClip() to set the bezier path as the clipping region. Any subsequent drawing commands will be masked to that region.

I use this wrapper function in one of my projects:

func drawLinearGradient(inside path:UIBezierPath, start:CGPoint, end:CGPoint, colors:[UIColor])
{
    guard let ctx = UIGraphicsGetCurrentContext() else { return }

    ctx.saveGState()
    defer { ctx.restoreGState() } // clean up graphics state changes when the method returns

    path.addClip() // use the path as the clipping region

    let cgColors = colors.map({ $0.cgColor })
    guard let gradient = CGGradient(colorsSpace: nil, colors: cgColors as CFArray, locations: nil)
        else { return }

    ctx.drawLinearGradient(gradient, start: start, end: end, options: [])
}