UIPrintInteractionController重复打印标签行为不一致问题求助
解决SwiftUI中AirPrint二次打印HTML标签偏移、尺寸异常问题
问题根源
UIPrintInteractionController.shared是全局单例,首次打印后部分配置(如纸张尺寸、缩放因子)会被缓存保留,而print(to:)方法不会自动重置这些状态,导致二次打印时格式异常。而presenter方式会触发打印机配置的重新校验,所以每次打印正常。
修复方案
每次打印时强制重置打印控制器的所有相关配置,避免残留状态干扰,具体代码修改如下:
// 每次打印前先清空单例的残留配置 let printController = UIPrintInteractionController.shared printController.printFormatter = nil printController.printInfo = nil // 重新创建打印信息 let printInfo = UIPrintInfo(dictionary: nil) printInfo.outputType = .photo printInfo.orientation = .landscape printController.printInfo = printInfo // 每次打印都创建新的格式化器实例 let formatter = UIMarkupTextPrintFormatter(markupText: [HtmlCode]) formatter.perPageContentInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) formatter.maximumContentWidth = 4 * 72.0 formatter.maximumContentHeight = 1.5 * 72 printController.printFormatter = formatter // 确保打印机实例配置最新 guard let printerURL = URL(string: "[PrinterURL]"), let printer = UIPrinter(url: printerURL) else { // 处理URL无效情况 return } // 先更新打印机信息,再执行打印 printer.updatePrinterInfo { [weak printController] success in guard success, let printController = printController else { return } printController.print(to: printer) }
额外优化建议
- 避免依赖单例残留状态:所有打印相关配置(printInfo、formatter)每次打印都重新创建,不复用之前的实例
- 强制同步打印机配置:调用
updatePrinterInfo确保获取打印机最新的纸张规格,避免使用缓存的旧配置 - 明确指定自定义纸张尺寸:通过代理方法强制设置纸张大小,确保打印内容匹配标签规格:
// 实现代理方法自定义纸张尺寸 extension YourViewOrController: UIPrintInteractionControllerDelegate { func printInteractionController(_ printInteractionController: UIPrintInteractionController, choosePaper numberOfCopies: Int, printInfo: UIPrintInfo, printer: UIPrinter, completionHandler: @escaping (UIPrintPaper?, Error?) -> Void) { let labelSize = CGSize(width: 4*72, height: 1.5*72) let customPaper = UIPrintPaper(paperSize: labelSize, borderRect: CGRect(origin: .zero, size: labelSize)) completionHandler(customPaper, nil) } } // 打印前设置代理 printController.delegate = self
验证注意事项
- 每次打印时确认
printController的printFormatter和printInfo都是新创建的实例 - 确保打印机URL有效,且
updatePrinterInfo回调成功后再执行打印
内容的提问来源于stack exchange,提问作者Simon Robitaille
相关产品推荐
相关产品推荐

