从WKWebView捕获window.print()

7

我正在尝试在我的应用程序中使用WKWebView捕获window.print() javascript调用,以实际显示打印对话框并允许用户从页面上呈现的按钮进行打印(而不是在我的应用程序内部的按钮)。 有人知道实现这一点的最佳方法吗?

目前,对于我来说,单击调用window.print()的链接什么都不做,只触发decidePolicyForNavigationAction委托方法,我找不到任何相关内容。


我可以问一下你正在打印哪个视图吗? - MobileOverlord
我正在打印WKWebView的viewPrintFormatter。 - Steve E
2个回答

16

发布后马上就想到了(显然)...希望这能帮助其他人。

在创建你的网页视图时...

let configuration = WKWebViewConfiguration()
let script = WKUserScript(source: "window.print = function() { window.webkit.messageHandlers.print.postMessage('print') }", injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: true)
configuration.userContentController.addUserScript(script)
configuration.userContentController.addScriptMessageHandler(self, name: "print")
self.webView = WKWebView(frame: CGRectZero, configuration: configuration)

那么只需在您的视图控制器中采用WKScriptMessageHandler协议并添加所需的方法即可...

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
    if message.name == "print" {
        printCurrentPage()
    } else {
        println("Some other message sent from web page...")
    }
}

func printCurrentPage() {
    let printController = UIPrintInteractionController.sharedPrintController()
    let printFormatter = self.webView.viewPrintFormatter()
    printController?.printFormatter = printFormatter

    let completionHandler: UIPrintInteractionCompletionHandler = { (printController, completed, error) in
        if !completed {
            if let e = error? {
                println("[PRINT] Failed: \(e.domain) (\(e.code))")
            } else {
                println("[PRINT] Canceled")
            }
        }
    }

    if let controller = printController? {
        if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
            controller.presentFromBarButtonItem(someBarButtonItem, animated: true, completionHandler: completionHandler)
        } else {
            controller.presentAnimated(true, completionHandler: completionHandler)
        }
    }
}

iPad上的self.browserController.addressBarActivityButton是什么? - Lukasz 'Severiaan' Grela
1
在iPad上,您必须从按钮/视图中呈现打印控制器。这只是我从项目中复制代码时留下的一个条形按钮项。 - Steve E

0

有一个用于挂钩 window.print() 的 未记录的 委托。

class MyApp: WKUIDelegate {
  func makeWebview() {
      ...
      self.webview.UIDelegate = self
  }
  func _webView(webView: WKWebView!, printFrame: WKFrameInfo) {
      println("JS: window.print()")
      printCurrentPage()
  }     
}

看起来很奇怪,他们公开了创建新窗口的委托方法,但却将这个私有化。希望他们将来会改变这一点。如果您不需要您的应用程序获得苹果的批准,那么这可能是一个不错的选择。 - Steve E
1
WebView的“private”方法并不是那么私有,很多人在App Store提交中使用它们,并且甚至在将它们提升为公共方法后支持下划线功能签名。一个例子是,苹果在iOS9 / OSX10.11中为WKWebView添加了一个新的私有方法:_printOperationWithPrintInfo:https://github.com/WebKit/webkit/commit/0dfc67a174b79a8a401cf6f60c02150ba27334e5 - kfix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接