我正在尝试将自定义绘图添加到 MacOS 中的 PDF 文档。(部署目标是 Big Sur 11.3)。我复制了 Apple 的 Custom Graphics iOS 示例代码 ( https://developer.apple.com/documentation/pdfkit/custom_graphics ),在此处根据 ebner 的 MacOS 代码对其稍作修改:如何在 PDF 文件上保存水印并导出到桌面 macOS莫哈韦。我在下面粘贴了我的代码。
问题:我的代码在每个页面上生成一个带有预期自定义绘图的 PDFView。然后它成功地将 pdf 保存到我计算机的文档文件夹中。我添加的任何 PDFAnnotations 都会被保存。draw(with:to:)
关于PDFPage 子类中的重写方法,原始页面(使用绘制的)被super.draw(with:to:)
保存,但此方法中的任何其他绘制都不会被保存。
我使用 Mac Catalyst 尝试了 Apple 的示例代码。它按预期工作,但我不想将 Mac Catalyst 用于我的应用程序。
如果有帮助,以下两行在设置委托之后但在保存文档之前放置(请参阅下面的代码注释位置),在示例代码和我的版本中产生不同的结果。示例代码的 PDFView 显示自定义绘图,而我的代码没有。
let data = document.dataRepresentation()!
pdfView.document = PDFDocument(data: data)
我在这里做错了什么有什么解释吗?感谢您的任何帮助!
其他注意事项:
- 一旦 PDFDocument
write(to:)
被调用,PDFPage 子类draw(with:to:)
就会在每个 PDF 页面被调用一次。正如预期的那样,super.draw(with:to:)
在此方法中删除会保存一个空白文档,除了任何 PDFAnnotations。 - 我已经成功保存了使用 CGContext 和 PDFPage's 创建的 PDF 文档
draw(with:to:)
,类似于 rob mayoff 在此处的回答:Draw on a PDF using Swift on macOS。但是,我正在尝试测试自定义页面绘图是否可以产生更小的最终文件大小(完整的细节可能与此处无关)。
完整代码:
class ViewController: NSViewController {
let pdfView = PDFView()
override func viewDidLoad() {
super.viewDidLoad()
/*
Set up view
*/
// Instantiate PDFDocument
guard let documentURL = Bundle.main.url(forResource: "Sample", withExtension: "pdf"),
let document = PDFDocument(url: documentURL) else { return }
// Set delegate
document.delegate = self
pdfView.document = document
// Code Note: See above.
// Save to documents folder
guard let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let destinationURL = documentDirectory.appendingPathComponent("Test").appendingPathExtension("pdf")
document.write(to: destinationURL)
}
}
extension ViewController: PDFDocumentDelegate {
func classForPage() -> AnyClass {
return WatermarkPage.self
}
}
class WatermarkPage: PDFPage {
override func draw(with box: PDFDisplayBox, to context: CGContext) {
// Draw original content
super.draw(with: box, to: context)
// Draw overlay string
// For iOS: UIGraphicsPushContext(context)
context.saveGState()
// For iOS: Flip context here
let string: NSString = "T E S T"
let attributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.foregroundColor: NSColor.black,
NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 64)
]
string.draw(at: CGPoint(x: 250, y: 250), withAttributes: attributes)
context.restoreGState()
// context.saveGState() // From ebner’s code; did not make a difference.
// For iOS: UIGraphicsPopContext()
}
}