I try to add an CAGradientLayer on top of a CAShapeLayer, but I can't get the full frame of the ShapeLayer without messing up the position of the GradientLayer, so the edges seems clipped. See photos below.
With GradientLayer:
Without GradientLayer:
This is the code:
class CircularProgressBarView: UIView {
// MARK: - Properties
var progressLayer = CAShapeLayer()
private var startPoint = CGFloat(-Double.pi / 2)
private var endPoint = CGFloat(3 * Double.pi / 2)
private var currentValue: Float = 0
var gradientLayer = CAGradientLayer()
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func layoutSubviews() {
super.layoutSubviews()
createCircularPath()
createGradientPath()
}
func createCircularPath() {
let circularPath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: frame.size.width / 2, startAngle: startPoint, endAngle: endPoint, clockwise: true)
progressLayer.path = circularPath.cgPath
progressLayer.fillColor = UIColor.clear.cgColor
progressLayer.lineCap = .round
progressLayer.lineWidth = 8
progressLayer.strokeEnd = 0
progressLayer.strokeColor = UIColor.white.cgColor
layer.addSublayer(progressLayer)
}
func createGradientPath() {
gradientLayer.type = CAGradientLayerType.conic
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)
gradientLayer.colors = [UIColor.yellow.cgColor, UIColor.red.cgColor]
gradientLayer.frame = self.bounds
gradientLayer.mask = progressLayer
layer.addSublayer(gradientLayer)
}
}


At a guess, you need to inset your gradient layer's frame by your line width. So use
self.bounds.insetBy(dx: lineWidth, dy: lineWidth)as your gradient view's frame.That should add lineWidth/2 space on all 4 edges of your gradient layer.
Edit:
Sorry, you need to inset your Circular path by lineWidth. Try editing it like this:
(Where I added an instance var
var lineWidth = 8.0)That produces this image on my simulator. (I made the parent view controller's view cyan so you can see what's going on with the
CircularProgressBarView.)