Search code examples
swiftuiviewlayeruibezierpathcagradientlayer

Add gradient color to a custom UIView


I realized a custom UIView class to a realize a sort of trapeze; following code I had used to realize the class:

import UIKit
import ChameleonFramework

class PolygonalView: UIView
{
    override init(frame: CGRect)
    {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {

        guard let context = UIGraphicsGetCurrentContext() else { return }

        context.beginPath()
        context.move(to: CGPoint(x: rect.minX, y: rect.minY))
        context.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        context.addLine(to: CGPoint(x: rect.maxX, y: 171))
        context.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        context.closePath()

        context.setFillColor(FlatSkyBlue().cgColor)
        context.fillPath()
    }
}

Then in my UIViewController I had create my view:

let pol = PolygonalView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 196))
        pol.backgroundColor = UIColor.clear

        self.view.addSubview(pol)

enter image description here

I achieved my goal, yep! But a problem has arisen: if I set a gradient, this gradient cover all the rectangular frame of the view. Following codes and image...

let gradientColor = CAGradientLayer()
        gradientColor.frame = pol.bounds
        gradientColor.colors = [FlatSkyBlue().cgColor, FlatSkyBlueDark().cgColor, FlatBlue().cgColor]
        gradientColor.startPoint = CGPoint(x: 0, y: 0)
        gradientColor.endPoint = CGPoint(x: 1, y: 1)
        pol.layer.addSublayer(gradientColor)

enter image description here

Any solutions to adapt the gradient to the real shape of my View?


Solution

  • Set the gradientColor layer's mask property to CAShapeLayer() that has the correct shape filled with black

     let mask = CAShapeLayer()
     mask.frame = // to whatever size it should be
     mask.path = yourShapeBezierHERE.cgPath
     mask.fillColor = UIColor.black.cgColor
     gradientColor.mask = mask