Macos drawRect:对于具有CametLayer的NSView,未调用
我有一个NSView的层备份(非层托管)子类,名为MetalView:Macos drawRect:对于具有CametLayer的NSView,未调用,macos,calayer,nsview,metal,Macos,Calayer,Nsview,Metal,我有一个NSView的层备份(非层托管)子类,名为MetalView: import Cocoa import Metal class MetalView: NSView { // MARK: Properties var metalLayer: CAMetalLayer { return layer as! CAMetalLayer } // MARK: - Overrides override func awakeFromNi
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")
}
}
未调用render方法。我尝试将WANTSUPDatalayer设置为true。使用I remove此部分调用render方法:
wantsLayer = true
metalLayer.delegate = self
metalLayer.device = MTLCreateSystemDefaultDevice()
metalLayer.pixelFormat = .BGRA8Unorm
metalLayer.framebufferOnly = true
从
wantsLayer
文档:
如果wantsUpdateLayer方法返回否,则不应直接与底层对象交互
在metalayer
上设置值,并将其帧计数修改为“直接与底层层对象交互”。在此配置中不允许这样做。这层不属于你。它属于系统。系统可以随时自由创建这些缓存层。它不必使用它,也不必只有一个。(核心动画通常会创建额外的层;这是完全正常的。)
如果要直接与图层交互,应将wantsUpdateLayer
设置为true
,然后在updateLayer
中实现图形代码。您不应该尝试将drawRect:
与直接处理的层混合
有关此问题的另一个版本,请参见我尝试将
wantsUpdateLayer
设置为true
并覆盖updateLayer
,但也不起作用。我还尝试将设置层的代码移动到makeBackingLayer
@GorGyolchanyan在设置WantUpdateLayer后,当您调用setNeedsDisplay时不会调用updateLayer?我手动调用了metalLayer.setNeedsDisplay()
,它只会导致方法displayLayer(layer:CALayer)无论WANTSUPDatalayer如何调用
。问题是它在调整视图大小时不会被调用。这是默认设置。您是否设置了layerContentsRedrawPolicy?除非您明确要求,否则图层通常避免重画。默认情况下,绝对不会进行边界更改(除非您要求完全重画,否则它们只是缩放或平移)。是的,确实有效,非常感谢。不过,另一个问题仍然存在:当我更新视图时,视图会闪烁并出现大量故障。