Reputation: 205
I have created a graph drawing points and creating a UIBezierPath between those points, but now I want to add a gradient to the plotted lines (similar to picture). The issue is I need a frame for the CAGradientLayer, which I do not know how to create given the plotted lines on a UIView. I have a stored array of CGPoint which contains all the points that are graphed, is there a way to create frame for the gradient with that array? Anyone know what to do here?
contains all points graphed
var graphedInvestedPoints = [CGPoint]()
func addGradient(){
let colorTop = UIColor(hexString: blueHexString)
let colorBottom = UIColor.white
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.locations = [0.0, 1.0]
//gradientLayer.frame = ?
self.layer.insertSublayer(gradientLayer, at: 0)
}
Upvotes: 0
Views: 306
Reputation: 77682
Here is one simple example, using a masked gradient layer.
Use your graphedInvestedPoints
to create the shape of the graph, apply that as the .path
property of a CAShapeLayer
and then apply that layer as the .mask
property of a CAGradientLayer
:
class GradientPathView: UIView {
let gradientLayer = CAGradientLayer()
let shapeLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
layer.addSublayer(gradientLayer)
// can be any opaque color
shapeLayer.fillColor = UIColor.white.cgColor
self.backgroundColor = .clear
}
override func layoutSubviews() {
super.layoutSubviews()
let path = UIBezierPath()
var pt: CGPoint = .zero
pt.x = 0
pt.y = bounds.maxY
// move to bottom-left corner
path.move(to: pt)
pt.y = bounds.maxY * 0.75
// add line up left side to first point on the graph line
path.addLine(to: pt)
// let's add 20 points across the X-axis
// decrementing Y to make an upward curve
let xInc: CGFloat = bounds.maxX / 20.0
var yInc: CGFloat = 1.0
for _ in 1...20 {
pt.x += xInc
pt.y -= yInc
path.addLine(to: pt)
yInc += 0.75
}
pt.x = bounds.maxX
pt.y = bounds.maxY
// add line to bottom-right corner
path.addLine(to: pt)
// close the path (bottom-right to bottom-left corners)
path.close()
shapeLayer.path = path.cgPath
gradientLayer.frame = bounds
let topColor: UIColor = .systemBlue
let botColor: UIColor = .white
gradientLayer.colors = [topColor.cgColor, botColor.cgColor]
// adjust startPoint / endPoint (or .locations) as desired
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
// apply mask to gradient layer
gradientLayer.mask = shapeLayer
}
}
Output on a 240 x 240 view (the red dashed-outline is just there to show the frame of the view):
Upvotes: 0