我有一个图层支持的(不 图层托管的) NSView 的子类,名为 MetalView :
import Cocoa
import Metal
class MetalView: NSView {
// MARK: Properties
var metalLayer: CAMetalLayer {
return layer as! CAMetalLayer
}
// MARK: - Overrides
override func awakeFromNib() {
super.awakeFromNib()
initialize()
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
render()
}
override func drawLayer(layer: CALayer, inContext ctx: CGContext) {
super.drawLayer(layer, inContext: ctx)
render()
}
override func displayLayer(layer: CALayer) {
super.displayLayer(layer)
render()
}
override func makeBackingLayer() -> CALayer {
return CAMetalLayer()
}
override var wantsUpdateLayer: Bool {
return false
}
// MARK: - Initialization
func initialize() {
// Layer
wantsLayer = true
metalLayer.delegate = self
metalLayer.device = MTLCreateSystemDefaultDevice()
metalLayer.pixelFormat = .BGRA8Unorm
metalLayer.framebufferOnly = true
}
// MARK: - Rendering
func render() {
// Rendering
metalLayer.frame = frame
NSLog("rendering")
}
}
未强制调用渲染方法。我尝试将 wantsUpdateLayer 设置为 true 。调用渲染方法,我删除此部分:
wantsLayer = true
metalLayer.delegate = self
metalLayer.device = MTLCreateSystemDefaultDevice()
metalLayer.pixelFormat = .BGRA8Unorm
metalLayer.framebufferOnly = true
答案 0 :(得分:3)
来自wantsLayer
文档:
如果wantsUpdateLayer方法返回NO,则不应直接与底层图层对象进行交互。
在metalLayer
上设置值并将其帧数修改为“直接与底层图层对象交互”。您不允许在此配置中执行此操作。该图层不属于您。它属于该系统。系统可以随时创建这些缓存层。它不必使用它,也不必只是一个。 (核心动画通常会创建额外的图层;这是完全正常的。)
如果您想直接与图层互动,则应将wantsUpdateLayer
设置为true
,然后在updateLayer
中实施图纸代码。您不应该尝试将drawRect:
与您直接混乱的图层混合在一起。
有关此问题的其他版本,请参阅Why is an empty drawRect interfering with a simple animation?