iOS 15系统PDFKit调用PDFPage.draw打印PDF首页文字重复异常
iOS 15 下 PDFPage.draw 接口打印首屏单词重复问题解决方案
问题现象
- 调用
PDFPage.draw接口打印PDF文件时,首页会出现首个单词不断重复的异常情况 - 该问题仅在iOS 15系统中出现,其余所有iOS版本均可正常打印对应页面
- 已知临时规避方案:在Acrobat中开启「optimized」选项重新保存文档可解决该问题,但无法保证所有用户上传PDF前都会执行该操作
异常效果示意图:
客户端侧修复方案(无需用户预处理PDF)
方案1:二次渲染规避解析Bug
iOS15的PDF解析器在首次渲染未优化的PDF时会出现文本流解析错误,可先将PDF页面渲染到临时图片上下文,再将图片绘制到打印上下文规避问题:
// Swift 适配代码示例 func fixedDrawPage(_ page: PDFPage, to context: CGContext, box: PDFDisplayBox = .mediaBox) { if #available(iOS 15.0, *) { let pageBounds = page.bounds(for: box) // 创建临时上下文渲染 UIGraphicsBeginImageContextWithOptions(pageBounds.size, false, 0) defer { UIGraphicsEndImageContext() } guard let tempCtx = UIGraphicsGetCurrentContext() else { page.draw(with: box, to: context) return } page.draw(with: box, to: tempCtx) guard let renderImg = UIGraphicsGetImageFromCurrentImageContext()?.cgImage else { page.draw(with: box, to: context) return } // 将渲染后的图片绘制到目标上下文 context.draw(renderImg, in: pageBounds) } else { // 其余系统版本走原有逻辑 page.draw(with: box, to: context) } }
方案2:预加载触发页面完整解析
在打印前提前触发PDF页面的内容解析逻辑,避免首次渲染时的解析错误:
// 预加载方法,打印前调用即可 func preloadPDFContent(_ doc: PDFDocument) { guard #available(iOS 15.0, *), doc.pageCount > 0 else { return } for i in 0..<doc.pageCount { guard let page = doc.page(at: i) else { continue } // 触发内部文本、布局解析 _ = page.bounds(for: .mediaBox) _ = page.attributedString } }
内容的提问来源于stack exchange,提问作者Nat Efimoff
相关产品推荐
相关产品推荐

