我正在使用标准的Cocoa绘图API在NSView上绘制图形。参见下图。在滚动视图中的NSView上有多个图形。每个图形都有大约1440个数据点,并且由于进行了重绘,因此滚动性能稍有下降。
有什么方法可以确保图形只绘制一次,以便图像可以平滑地上下滚动?
该视图用于生成PDF输出文件。
除非调整视图的大小,否则实际上不需要更改图形,并且这种情况不会发生,有什么方法可以防止视图在滚动过程中自行重绘。希望有一个简单的开关来确保视图绘制一次并保存在内存中!
基本代码在NSView子类draw()函数中。
override func draw(_ dirtyRect: NSRect) {
drawAxis()
// Only draw the graph axis during live resize
if self.inLiveResize {
return
}
plot1()
plot2()
plot3()
...
}
func plot1(){
for value in plot1Data {
path = NSBezierPath()
if isFirst {
path?.move(to: value)
} else {
path?.line(to: value)
}
}
}
最佳答案
苹果在其View Programming Guide: Optimizing View Drawing文章中提供了非常全面的建议。
似乎您甚至没有采取最少的步骤来避免绘制不必要的图形。例如,您显示的代码不会检查dirtyRect
来查看给定图是否完全落在该图之外,因此无需绘制。
但是,如该文章所述,使用getRectsBeingDrawn(_:count:)
和/或needsToDraw(_:)
方法通常可以做得更好。
在某些情况下,滚动视图可以保存已绘制的内容,因此您的视图不需要重新绘制它。请参见release notes for Responsive Scrolling。但是,此要求之一是您的视图必须不透明。它需要覆盖isOpaque
以返回true。但是,仅仅声称自己是不透明的还不够。通过在每次调用draw()
时绘制整个脏矩形,您的视图实际上必须是不透明的。您可以在进行其他绘制以满足此要求之前,用背景色填充脏矩形。
确保剪辑视图的copiesOnScroll
属性也设置为true。这可以在IB(尽管它是作为滚动视图的属性显示)中或在代码中完成的。默认情况下应为true。
请注意,作为响应滚动的一部分的透支将在空闲时间逐渐增加。这将涉及重复调用视图的draw()
方法。如果您还没有将其优化为仅绘制与脏矩形相交的对象,那么这些调用将变得缓慢/昂贵。因此,请务必进行优化。
关于macos - 如何优化 cocoa 绘制以确保平滑滚动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41292969/