在 iOS 中创建具有渐变的折线图
Create a line graph with gradients in iOS
在 iOS 中创建这样的图表的最佳方法是什么?
我的第一个想法是创建一个贝塞尔曲线路径,然后添加一个具有不同位置的渐变层。但这行不通,因为文档指定:
The values must be monotonically increasing.
我的图中不是这种情况。
有什么好的方法可以实现这个目标吗?
谢谢
您可以使用 CAGradientLayer
作为图表背景,然后使用 CAShapeLayer
作为渐变层的遮罩来实现。遮罩层将仅在其绘制区域中显示下面的层。
这个 playground 代码使用随机生成的数据给出了一个总体思路:
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
view.backgroundColor = .black
// Gradient for the chart colors
let gradient = CAGradientLayer()
gradient.colors = [
UIColor.red.cgColor,
UIColor.orange.cgColor,
UIColor.yellow.cgColor,
UIColor.green.cgColor
]
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
gradient.frame = view.bounds
view.layer.addSublayer(gradient)
// Random points
let graph = CAShapeLayer()
let path = CGMutablePath()
var y: CGFloat = 150
let points: [CGPoint] = stride(from: CGFloat.zero, to: 300, by: 2).map {
let change = CGFloat.random(in: -20...20)
var newY = y + change
newY = max(10, newY)
newY = min(newY, 300)
y = newY
return CGPoint(x: [=10=], y: y)
}
path.addLines(between: points)
graph.path = path
graph.fillColor = nil
graph.strokeColor = UIColor.black.cgColor
graph.lineWidth = 4
graph.lineJoin = .round
graph.frame = view.bounds
// Only show the gradient where the line is
gradient.mask = graph
PlaygroundPage.current.liveView = view
结果:
在 iOS 中创建这样的图表的最佳方法是什么?
我的第一个想法是创建一个贝塞尔曲线路径,然后添加一个具有不同位置的渐变层。但这行不通,因为文档指定:
The values must be monotonically increasing.
我的图中不是这种情况。
有什么好的方法可以实现这个目标吗?
谢谢
您可以使用 CAGradientLayer
作为图表背景,然后使用 CAShapeLayer
作为渐变层的遮罩来实现。遮罩层将仅在其绘制区域中显示下面的层。
这个 playground 代码使用随机生成的数据给出了一个总体思路:
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
view.backgroundColor = .black
// Gradient for the chart colors
let gradient = CAGradientLayer()
gradient.colors = [
UIColor.red.cgColor,
UIColor.orange.cgColor,
UIColor.yellow.cgColor,
UIColor.green.cgColor
]
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
gradient.frame = view.bounds
view.layer.addSublayer(gradient)
// Random points
let graph = CAShapeLayer()
let path = CGMutablePath()
var y: CGFloat = 150
let points: [CGPoint] = stride(from: CGFloat.zero, to: 300, by: 2).map {
let change = CGFloat.random(in: -20...20)
var newY = y + change
newY = max(10, newY)
newY = min(newY, 300)
y = newY
return CGPoint(x: [=10=], y: y)
}
path.addLines(between: points)
graph.path = path
graph.fillColor = nil
graph.strokeColor = UIColor.black.cgColor
graph.lineWidth = 4
graph.lineJoin = .round
graph.frame = view.bounds
// Only show the gradient where the line is
gradient.mask = graph
PlaygroundPage.current.liveView = view
结果: