Печать содержимого WKWebView (OS X)
Я пытаюсь распечатать содержимое WkWebView
, но когда появится панель печати, предварительный просмотр печати пуст.
Вот код:
- (void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
_webView = [[WKWebView alloc] initWithFrame:self.webViewOutlet.frame configuration:config];
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com"]]];
[_webViewOutlet addSubview:_webView];
_webView.navigationDelegate = self;
}
У меня есть выход для WkWebView
, поэтому я могу видеть, загружен ли он, и я помещаю вызов print
в метод делегата didFinishNavigation
, как это, чтобы быть уверенным:
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
[self.webView print:nil];
}
Независимо от того, что делает страница, предварительный просмотр печати всегда является пустой страницей. Я также попытался использовать NSPrintOperation
, и результаты были одинаковыми - превью на печать и сохраненные PDF файлы были пустыми страницами.
Любые идеи, что я делаю неправильно? Есть ли другой способ печати/преобразования WkWebView
в PDF? Предложения приветствуются. Спасибо.
Ответы
Ответ 1
Если вашему приложению может потребоваться macOS 10.13 или более поздняя версия, в WKWebView есть новый метод: takeSnapshot (with: completeHandler :), который генерирует представление NSImage вашего веб-представления.
Насколько я знаю, это лучший вариант для рендеринга WKWebView для изображения.
Ответ 2
Решение, которое я использую, состоит в том, чтобы создать экземпляр старого доброго объекта WebView и использовать метод печати этого объекта. Мой пример использует HTML-строку в качестве отправной точки, но она должна быть легко адаптируемой к URL.
Цель С
@interface WebPrinter ()
{
WebView *printView;
NSPrintInfo *printInfo;
}
@implementation WebPrinter
- (void)printHtml:(NSString *)html {
if (!printInfo) {
printInfo = [NSPrintInfo sharedPrintInfo];
printInfo.topMargin = 25;
printInfo.bottomMargin = 10;
printInfo.rightMargin = 10;
printInfo.leftMargin = 10;
}
NSRect printViewFrame = NSMakeRect(0, 0, printInfo.paperSize.width, printInfo.paperSize.height);
printView = [[WebView alloc] initWithFrame:printViewFrame frameName:@"printFrame" groupName:@"printGroup"];
printView.shouldUpdateWhileOffscreen = true;
printView.frameLoadDelegate = self;
[printView.mainFrame loadHTMLString:html baseURL:NSBundle.mainBundle.resourceURL];
}
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
if (frame != sender.mainFrame) {
return;
}
if (sender.isLoading) {
return;
}
if ([[sender stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) {
sender.frameLoadDelegate = nil;
NSWindow *window = NSApp.mainWindow;
if (!window) {
window = NSApp.windows.firstObject;
}
NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: frame.frameView.documentView printInfo:printInfo];
[printOperation runOperationModalForWindow:window delegate:window didRunSelector:nil contextInfo:nil];
}
}
@end
стриж
class WebPrinter: NSObject, WebFrameLoadDelegate {
let window: NSWindow
var printView: WebView?
let printInfo = NSPrintInfo.shared
init(window: NSWindow) {
self.window = window
printInfo.topMargin = 30
printInfo.bottomMargin = 15
printInfo.rightMargin = 0
printInfo.leftMargin = 0
}
func printHtml(_ html: String) {
let printViewFrame = NSMakeRect(0, 0, printInfo.paperSize.width, printInfo.paperSize.height)
if let printView = WebView(frame: printViewFrame, frameName: "printFrame", groupName: "printGroup") {
printView.shouldUpdateWhileOffscreen = true
printView.frameLoadDelegate = self
printView.mainFrame.loadHTMLString(html, baseURL: Bundle.main.resourceURL)
}
}
func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
if frame != sender.mainFrame {
return
}
if sender.isLoading {
return
}
if sender.stringByEvaluatingJavaScript(from: "document.readyState") == "complete" {
sender.frameLoadDelegate = nil
let printOperation = NSPrintOperation(view: frame.frameView.documentView, printInfo: printInfo)
printOperation.runModal(for: window, delegate: window, didRun: nil, contextInfo: nil)
}
}
}
Ответ 3
Вы можете распечатать содержимое WKWebView
с помощью viewPrintFormatter
.
Вот пример кода:
if ([UIPrintInteractionController isPrintingAvailable])
{
UIPrintInfo *pi = [UIPrintInfo printInfo];
pi.outputType = UIPrintInfoOutputGeneral;
pi.jobName = @"Print";
pi.orientation = UIPrintInfoOrientationPortrait;
pi.duplex = UIPrintInfoDuplexLongEdge;
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
pic.printInfo = pi;
pic.showsPageRange = YES;
pic.printFormatter = self.webView.viewPrintFormatter;
[pic presentFromBarButtonItem:barButton animated:YES completionHandler:^(UIPrintInteractionController *printInteractionController, BOOL completed, NSError *error) {
if(error)
NSLog(@"handle error here");
else
NSLog(@"success");
}];
}