如何在 macOS 上在自定义 CALayer 子类的覆盖绘制函数中绘制字符串?



为什么下面的代码没有在 macOS 应用程序中绘制字符串?

class MyLayer: CALayer {
override func draw(in ctx: CGContext) {
let font = NSFont.systemFont(ofSize: 18)
let text = "TEXT"
let textRect = CGRect(x: 100, y: 100, width: 100, height: 100)
text.draw(in: textRect, withAttributes: [.font: font])
}
}

CALayerdraw(in:)方法建立在Core Graphics之上。所有 Core Graphics 绘图函数都以CGContext作为参数(或者在 Swift 中,是CGContext上的方法)。这就是核心动画将CGContext传递给draw(in:)方法的原因。

但是,String上的draw(in:withAttributes:)方法不是核心图形的一部分。它是AppKit的一部分。AppKit 的绘制方法不直接在CGContext上运行。它们在NSGraphicsContext(包裹CGContext)上运行。但是,正如您从draw(in:withAttributes:)方法中看到的那样,AppKit 的绘图函数不采用NSGraphicsContext参数,也不是NSGraphicsContext上的方法。

相反,有一个全局(每线程)NSGraphicsContext。AppKit 绘制方法使用此全局上下文。由于您是在核心动画级别编写代码,因此 AppKit 没有为您设置全局NSGraphicsContext。您需要自己设置:

class MyLayer: CALayer {
override func draw(in ctx: CGContext) {
let nsgc = NSGraphicsContext(cgContext: ctx, flipped: false)
NSGraphicsContext.current = nsgc
let font = NSFont.systemFont(ofSize: 18)
let text = "TEXT"
let textRect = CGRect(x: 100, y: 100, width: 100, height: 100)
text.draw(in: textRect, withAttributes: [.font: font])
}
}

最新更新