如何缓存图层内容并在调整大小/动画期间使用它?

时间:2017-10-04 09:26:06

标签: swift macos cocoa core-animation

我注意到在macOS的Finder中,当侧边栏折叠/展开时,图标和文本会被压缩或拉伸(见下面的屏幕截图)。我想这是一种优化,可以防止图层在动画过程中重新绘制。

我尝试编写一个模仿该行为的自定义NSTableCellView子类。但我不知道从哪里开始,具体来说:

  1. 如何在动画开始时收到通知,以便我可以设置图层的内容。
  2. 如何在动画完成时重新绘制视图或图层,以便它不再使用缓存的内容。
  3. 我从以下脚手架代码开始。 (当draw(_ dirtyRect: NSRect)返回wantsUpdateLayer时,系统不会调用true方法。这可能是根据this doc进行的优化。

         class TableCellView: NSTableCellView {
    
            override func draw(_ dirtyRect: NSRect) {
                print(#file, #line, "draw tcell view")
                super.draw(dirtyRect)
    
                // Drawing code here.
            }
    
            override var wantsUpdateLayer: Bool {
                print(#file, #line, "want")
                return true
            }
    
            override func updateLayer() {
                print(#file, #line, "update")
                super.updateLayer()
            }
    
        }
    

    enter image description here

1 个答案:

答案 0 :(得分:0)

如果视图使用图层作为其后备存储(wantsLayer = true),则可以设置视图layerContentsRedrawPolicy以执行这些相同的优化。默认情况下(如果AppKit创建了图层),在动画调整大小期间,内容将不断重新绘制到视图的背景层中:

  

对于图层支持的视图 - 即AppKit为其创建图层的视图 - 默认情况下,AppKit会将内容重绘策略设置为duringViewResize

例如,将策略设置为beforeViewResize,视图将在调整大小动画的开头重绘一次。

NSView.LayerContentsRedrawPolicy列出了所有可能的重绘政策。