ios - 在选择打印机之前获取空白 View

标签 ios printing swiftui

当我调用以下代码时,在获得打印机选择 View 之前,我会看到一个空白 View 。一旦我关闭(滑动)空白 View ,之后一切似乎都正常。调用代码如下所示。我在另一个 View 中定义了一个 NavigationView,该 View 导致了进行此调用的 View 。有什么建议么?

struct PrintHTMLView: UIViewControllerRepresentable
{
    var htmlString: String
    var title: String
    
    typealias UIViewControllerType = UIViewController
    
    fileprivate let controller = UIViewController()
    
    func makeUIViewController(context: Context) -> UIViewController
    {
        controller
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context)
    {
       let printInfo = UIPrintInfo(dictionary: nil)
       printInfo.jobName = title
       printInfo.outputType = .general
            
       let printController = UIPrintInteractionController.shared
       printController.printInfo = printInfo
       printController.showsNumberOfCopies = true
            
       let formatter = UIMarkupTextPrintFormatter(markupText: htmlString)
       formatter.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72)
       printController.printFormatter = formatter     
       printController.present(animated: true, completionHandler: nil)
    }
}
调用上述代码的代码片段......
Button("Print")
{
  self.printShowing.toggle()
}.sheet(isPresented: $printShowing)
{
  PrintHTMLView(htmlString: html, title: "Report")
}

最佳答案

这是固定的变体。重点是UIPrintInteractionController显示自己的工作表,因此不需要它,updateUIViewController目的不同 - 更新外部数据变化的内容,所以所有的准备都应该在makeUIViewController .
注:UIMarkupTextPrintFormatter引用应保留在属性中,否则它会丢失并导致打印表关闭时崩溃。
使用 Xcode 12/iOS 14 测试
demo

struct PrintHTMLView: UIViewControllerRepresentable
{
    let title: String
    let formatter: UIMarkupTextPrintFormatter
    let callback: () -> ()

    init(htmlString: String, title: String, completion: @escaping () -> () = {}) {
        self.title = title
        self.callback = completion

        formatter = UIMarkupTextPrintFormatter(markupText: htmlString)
        formatter.perPageContentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72)
    }

    func makeUIViewController(context: Context) -> UIViewController
    {
        let printInfo = UIPrintInfo(dictionary: nil)
        printInfo.jobName = title
        printInfo.outputType = .general

        let printController = UIPrintInteractionController.shared
        printController.printInfo = printInfo
        printController.showsNumberOfCopies = true

        printController.printFormatter = formatter

        let controller = UIViewController()
        DispatchQueue.main.async {
            printController.present(animated: true, completionHandler: { _, _, _ in
                printController.printFormatter = nil
                self.callback()
            })
        }
        return controller
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context)
    {
    }
}

struct TestPrintController: View {
    @State private var printShowing = false
    var body: some View {
        Button("Print")
        {
            self.printShowing = true
        }
        .background(Group {
            if self.printShowing {
                PrintHTMLView(htmlString: "Test String", title: "Report") {
                    self.printShowing = false
                }
            }
        })

    }
}

关于ios - 在选择打印机之前获取空白 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62999655/

相关文章:

iphone - 以编程方式选择 UIView

java - 无法打印到同一行

ios - SwiftUI 上下文菜单 : Set shape of shadow or hide it

swift - 如何将完成 block 添加到 SwiftUI .alert(isPresented)

ios - SwiftUI 上的 NavigationLink 推送 View 两次

ios - 在 Objective-C 项目中导入 Swift 框架 - 错误 - 未知类型名称

iphone - AdMob (iOS) 上的实现

ios - tableView 单元格中标签的框架大小不会改变

javascript - 从多个 Canvas 制作图像

c# - 打印excel文档时设置打印机托盘