SwiftUI Mac应用:URL转PDFDocument后NSPrintOperation打印排版异常求助
问题:SwiftUI Mac应用打印PDF排版异常,内容截断无法适配纸张宽度
我正在使用SwiftUI开发Mac应用,通过URL获取PDFDocument后,点击按钮用NSPrintOperation打印文档。目前功能能运行,但打印时排版异常,PDF内容被严重截断,像是叠在其他文档上,希望让PDF占满纸张宽度(忽略纸张上原有方框)。测试用PDF链接:https://www.soundczech.cz/temp/lorem-ipsum.pdf

现有代码
import SwiftUI import PDFKit import AppKit struct ContentView: View { let pdfDocumentUrl = URL(string: "https://www.soundczech.cz/temp/lorem-ipsum.pdf")! var body: some View { VStack { Button("Print PDF") { let pdf = PDFDocument(url: pdfDocumentUrl)! printPDFDocumentt(pdf) } } .padding() } func printPDFDocumentt(_ document: PDFDocument) { let pdfView = PDFView(frame: .init(x: 0, y: 0, width: document.page(at: 0)?.bounds(for: .mediaBox).width ?? 0, height: document.page(at: 0)?.bounds(for: .mediaBox).height ?? 0)) pdfView.document = document pdfView.backgroundColor = .clear let printInfo = NSPrintInfo.shared printInfo.horizontalPagination = .fit printInfo.verticalPagination = .fit printInfo.orientation = .portrait let printOperation = NSPrintOperation(view: pdfView, printInfo: printInfo) printOperation.run() } }
解决方案
问题根源在于通过PDFView作为打印视图时的适配逻辑缺失,以及NSPrintInfo的配置不够精准。以下是两种可行的修复方案:
方案一:直接调用PDFDocument的打印方法(推荐)
无需手动创建PDFView,利用PDFDocument自带的打印方法,系统会自动处理PDF与纸张的适配逻辑:
func printPDFDocumentt(_ document: PDFDocument) { let printInfo = NSPrintInfo.shared printInfo.horizontalPagination = .fit printInfo.verticalPagination = .fit // 根据PDF页面尺寸自动匹配打印方向 if let firstPage = document.page(at: 0) { let pageBounds = firstPage.bounds(for: .mediaBox) printInfo.orientation = pageBounds.width > pageBounds.height ? .landscape : .portrait } // 设置边距为0,让内容尽可能占满纸张 printInfo.topMargin = 0 printInfo.bottomMargin = 0 printInfo.leftMargin = 0 printInfo.rightMargin = 0 document.print(with: printInfo, displayPrintDialog: true) }
方案二:调整PDFView的适配配置
如果必须保留PDFView作为打印视图,需要完善其缩放和尺寸设置:
func printPDFDocumentt(_ document: PDFDocument) { guard let firstPage = document.page(at: 0) else { return } let pageBounds = firstPage.bounds(for: .mediaBox) let pdfView = PDFView() pdfView.document = document pdfView.backgroundColor = .clear // 开启自动缩放,让PDF适配视图尺寸 pdfView.autoScales = true pdfView.displayMode = .singlePage // 设置缩放因子为适配视图的比例 pdfView.scaleFactor = pdfView.scaleFactorForSizeToFit let printInfo = NSPrintInfo.shared printInfo.horizontalPagination = .fit printInfo.verticalPagination = .fit printInfo.orientation = pageBounds.width > pageBounds.height ? .landscape : .portrait // 清除边距限制 printInfo.topMargin = 0 printInfo.bottomMargin = 0 printInfo.leftMargin = 0 printInfo.rightMargin = 0 let printOperation = NSPrintOperation(view: pdfView, printInfo: printInfo) // 让打印视图的尺寸匹配纸张尺寸 printOperation.view.frame = CGRect(x: 0, y: 0, width: printInfo.paperSize.width, height: printInfo.paperSize.height) printOperation.run() }
关键修改说明
- 直接使用
PDFDocument的打印方法是最可靠的方式,系统内部会处理PDF页面与打印纸张的适配 - 设置
NSPrintInfo的边距为0,避免默认边距导致内容被截断 - 若使用
PDFView,必须开启autoScales并让视图尺寸匹配纸张尺寸,确保缩放逻辑生效
内容的提问来源于stack exchange,提问作者Trey6
相关产品推荐
相关产品推荐

