前言
最近笔者在绘制股票折线图时,发现绘图时,线条的转折处有很明显的的锯齿!于是笔者开启了消除“锯齿”之路。。。
锯齿感示例图
解决方法
在网上尝试了许多方法,例如开启消除锯齿等方法都没有,最后发现因为path的stroke时机调用错了,因此导致绘图产生了锯齿感。接下来看代码:
class LineView: UIView {
override func draw(_ rect: CGRect) {
let testData: [CGFloat] = [10, 50, 40, 60, 30, 70, 20, 80, 10, 100, 10, 50, 40, 60, 30, 70, 20, 80, 10, 100]
let stepX: CGFloat = (self.frame.width - 10) / CGFloat(testData.count)
let maxY: CGFloat = 100
let height = self.frame.height - 10
let stepY = height / maxY
let path = UIBezierPath()
var isFirstPoint: Bool = true
for (index, value) in testData.enumerated() {
let x = stepX * CGFloat(index) + 5
let y = (maxY - value) * stepY
if isFirstPoint {
path.move(to: CGPoint(x: x, y: y))
isFirstPoint = false
}else {
path.addLine(to: CGPoint(x: x, y: y))
}
UIColor.red.setStroke()
path.stroke() //注意这句话
}
}
}
可以带出,path.stroke()是在每次for循环结束后都会执行一次的,而万万没想到的是,这就是造成锯齿的原因!只需要把path.stroke()的调用放在for循环的括号外,问题即可解决。放出的代码如下:
class LineView: UIView {
override func draw(_ rect: CGRect) {
let testData: [CGFloat] = [10, 50, 40, 60, 30, 70, 20, 80, 10, 100, 10, 50, 40, 60, 30, 70, 20, 80, 10, 100]
let stepX: CGFloat = (self.frame.width - 10) / CGFloat(testData.count)
let maxY: CGFloat = 100
let height = self.frame.height - 10
let stepY = height / maxY
let path = UIBezierPath()
var isFirstPoint: Bool = true
for (index, value) in testData.enumerated() {
let x = stepX * CGFloat(index) + 5
let y = (maxY - value) * stepY
if isFirstPoint {
path.move(to: CGPoint(x: x, y: y))
isFirstPoint = false
}else {
path.addLine(to: CGPoint(x: x, y: y))
}
}
UIColor.red.setStroke() // 变动的地方
path.stroke() // 变动的地方
}
}
修复后:
总结
就因为这个path的调用时机弄错了,耗费了我大量的时间,因此记录下来,防止自己也好,帮助到大家解决问题也好~因此我猜测,quart2D的path描述时,把所有的点都描述完后,在stroke,该库会自动帮我们修复锯齿感等一些问题。