This question is about printing ALL content (including off screen content) of WKWebView. Currently (still, as of iOS 10.2 or OSX 10.12) there is NO working solution and none of the supposed solutions on Stackoverflow work. Only provide an answer here if you have verified for yourself that you can print OFF SCREEN CONTENT, and if you did then provide the working example code.
I'm trying to print ALL the content of a WKWebView or WebView on OSX 10.10 or above (Currently running on 10.11.2). For example, a wide html table where columns are out of view and off to the right. Earlier versions of OSX would automatically paginate and correctly print all the html.
I've tried using the solutions available here on Stackoverflow and elsewhere. All essentially say the same thing which is to print the documentView
like so:
[[NSPrintOperation printOperationWithView:_webView.mainFrame.frameView.documentView printInfo:pInfo] runOperation];
This stopped working for both WKWebView or WebView in 10.10. If you do this:
[[NSPrintOperation printOperationWithView:_wkWebView printInfo:pInfo] runOperation];
You get pagination but the printout includes scroll bars WebView
, and the other WKWebView
gives you blank pages.
I can't find any mention whatsoever in Apple documentation about printing for WKWebView on OSX. Nor can I find any answer that is OSX specific and not iOS.
Does anyone have ANY idea how to print these on OSX?
UPDATE: This is a bug in WebView [Radar:23159060] (still open 2/2018) and WKWebView does not even appear to address printing on OSX. After examining the Open Source for this class on the net, I see that all of the classes that have anything to do with printing are in a conditional compilation block that only supports platform: iOS.
UPDATE Part Deux: Amazingly this ridiculous bug exists in ALL implementations of this class including those on iOS! I find it ridiculous that this is still not fixed at this late date despite the documentation's statement to use this (and only this class) in Apps that support iOS 8 or above. It is now IMPOSSIBLE to print all the on screen and off screen content of a WebView on either iOS or OSX. Fail Apple. Time to FIX THIS! We all know what Steve would've said about it....
UPDATE Part THREE :)- Yet still more amazing is that this issue is NOT resolved as of 10.15.2 and coming up on 4+ YEARS!!! this issue has been floating around (Apple waaaaaake up up up up....). It's kind of amazing considering they're getting very pushy about using WKWebView and over in iOS land even rejecting Apps that don't (unless you're trying to support iOS 7).
UPDATE Part FOUR (2020... can you believe it?!?): As of Big Sur, this is still an issue. I solved it by writing a work around see accepted answer below:
printOperationWithPrintInfo:
DOES NOT print all content which is off screen or scrolled out of view in either the Horizontal or vertical direction. It does however use your Print CSS which is a slight advantage over:
- (void)takeSnapshotWithConfiguration:(WKSnapshotConfiguration *)snapshotConfiguration
completionHandler:(void (^)(NSImage *snapshotImage, NSError *error))completionHandler;
To get it to work I did:
NSPrintInfo *pInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
pInfo.horizontalPagination = NSPrintingPaginationModeAutomatic;
pInfo.verticalPagination = NSPrintingPaginationModeAutomatic;
pInfo.verticallyCentered = YES;
pInfo.horizontallyCentered = YES;
pInfo.orientation = NSPaperOrientationLandscape;
pInfo.leftMargin = 30;
pInfo.rightMargin = 30;
pInfo.topMargin = 30;
pInfo.bottomMargin = 30;
NSPrintOperation *po = [_webView printOperationWithPrintInfo:pInfo];
po.showsPrintPanel = YES;
po.showsProgressPanel = YES;
// Without the next line you get an exception. Also it seems to
// completely ignore the values in the rect. I tried changing them
// in both x and y direction to include content scrolled off screen.
// It had no effect whatsoever in either direction.
po.view.frame = _webView.bounds;
// [printOperation runOperation] DOES NOT WORK WITH WKWEBVIEW, use
[po runOperationModalForWindow:self.view.window delegate:self didRunSelector:@selector(printOperationDidRun:success:contextInfo:) contextInfo:nil];
**Also there is something going on I don't fully understand. It doesn't seem to matter what size your wkWebView is. If I size the App to hide some of the content it still seems to grab as much that IS off screen as will fit on the page specified, but it doesn't seem to know how to paginate content that will not fit on the page size onto other pages. So that appears to be where the issue is. There may be some way around this and if anyone has a clue post it here!!
See Question&Answers more detail:
os