问题描述
我通过 CAShapeLayer
中的 MTKView
创建了一个折线图。在某些情况下,此折线图每秒更新一次,但在当前的实现中,每当图表更新(每秒)时,都会有一个微小的冻结时刻,因为它会再次绘制所有内容。我尝试了所有我能想到的方法来提高它的性能,但我无法修复它。当新数据到来时,这个冻结时刻不允许图表平滑移动。
这是我的代码的一部分:
class LineChartView: MTKView,uiscrollviewdelegate {
private let scrollView: UIScrollView = UIScrollView()
public var lineGap: CGFloat = 0.7
var dataEntries: [PointEntry]? {
didSet {
dispatchQueue.main.async {
self.setNeedsLayout()
}
}
}
private var hrDataPoints: [CGPoint]?
override func layoutSubviews() {
if let dataEntries = dataEntries {
scrollView.frame = CGRect(x: 50,y: 0,width: frame.size.width,height: frame.size.height)
scrollView.contentSize = CGSize(width: 50 + CGFloat(dataEntries.count) * lineGap,height: frame.size.height)
mainLayer.frame = CGRect(x: 0,width: CGFloat(dataEntries.count) * lineGap,height: frame.size.height)
dataLayer.frame = CGRect(x: 0,y: topSpace,width: mainLayer.frame.width,height: mainLayer.frame.height - topSpace - bottomSpace)
hrDataPoints = convertDataEntriesToPoints(entries: dataEntries)
clean()
drawCharts()
}
}
}
// MARK: - Drawing
extension LineChartView {
private func convertDataEntriesToPoints(entries: [PointEntry]) -> [CGPoint] {
if let max = entries.max()?.value,let min = entries.min()?.value {
let filteredMax = max + emptySpaceAboveAndBelowChart
let filteredMin = min - emptySpaceAboveAndBelowChart
var result: [CGPoint] = []
let minMaxrange: CGFloat = CGFloat(filteredMax - filteredMin) * topHorizontalLine
for i in 0 ..< entries.count {
let height = dataLayer.frame.height * (1 - ((CGFloat(entries[i].value) - CGFloat(filteredMin)) / minMaxrange))
let point = CGPoint(x: CGFloat(i) * lineGap + 40,y: height)
result.append(point)
}
return result
}
return []
}
private func drawCharts() {
let lineLayer = CAShapeLayer()
lineLayer.linewidth = 2
lineLayer.fillColor = UIColor.clear.cgColor
guard let path = createPath() else { return }
lineLayer.path = path.cgPath
lineLayer.strokeColor = UIColor.green.cgColor
lineLayer.drawsAsynchronously = true
dataLayer.addSublayer(lineLayer)
}
private func createPath() -> UIBezierPath? {
var dataPoints: [CGPoint] = []
guard let points = hrDataPoints,points.count > 0 else { return nil }
dataPoints = points
let path = UIBezierPath()
path.move(to: dataPoints[0])
for i in 1 ..< dataPoints.count {
path.addLine(to: dataPoints[i])
}
return path
}
}
// MARK: - Cleaning
extension LineChartView {
private func clean() {
mainLayer.sublayers?.forEach({
if $0 is CATextLayer {
$0.removeFromSuperlayer()
}
})
gridLayer.sublayers?.forEach({ $0.removeFromSuperlayer() })
dataLayer.sublayers?.forEach({ $0.removeFromSuperlayer() })
}
}
并且在新数据到来的每一秒内,新数据都会附加到 dataEntries
中。如果有人能给我一些建议,我将不胜感激。
谢谢
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)