Cocoa osx PDFView NSPrintOperation PrintPanel没有显示页面预览

时间:2015-05-06 14:54:37

标签: macos cocoa pdfview nsprintoperation

在我的Mac应用中,我有一个显示一些HTML内容的webview。我从该webview创建一个PDFDocument,然后我想打印该文档。所以我从文档创建一个PDFView,然后调用NSPrintOperation printOperationWithView。显示打印面板时,除了显示为空白的页面预览外,所有内容都显示正确,但如果按下详细信息按钮,则会刷新面板并正确显示页面预览。

我该如何解决? 需要帮助。提前谢谢。

这是我的问题的一个例子:

1-打印面板显示空白页面预览。接下来我按显示详细信息。

enter image description here

2-刷新面板后,页面预览显示正确。

enter image description here

这是我的代码:

NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
[printInfo setTopMargin:0.0];
[printInfo setBottomMargin:0.0];
[printInfo setLeftMargin:0.0];
[printInfo setRightMargin:0.0];
[printInfo setHorizontalPagination:NSFitPagination];
[printInfo setVerticalPagination:NSAutoPagination];
[printInfo setVerticallyCentered:NO];
[printInfo setHorizontallyCentered:YES];

NSData *pdfFinal = [[[[webView mainFrame] frameView] documentView] dataWithPDFInsideRect:[[[webView mainFrame] frameView] documentView].frame];

PDFDocument *doc = [[PDFDocument alloc] initWithData:pdfFinal];
PDFView *pdfView = [[PDFView alloc] init];
[pdfView setDocument:doc];

NSPrintOperation *op;
op = [NSPrintOperation printOperationWithView:pdfView.documentView printInfo:printInfo];

[op setShowsProgressPanel:YES];
[op setShowsPrintPanel:YES];
[op runOperation];

2 个答案:

答案 0 :(得分:2)

来自this链接:

PDFDocument *doc = ...;

// Invoke private method.
// NOTE: Use NSInvocation because one argument is a BOOL type. Alternately, you could declare the method in a category and just call it.
BOOL autoRotate = NO; // Set accordingly.
NSMethodSignature *signature = [PDFDocument instanceMethodSignatureForSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)];
[invocation setArgument:&printInfo atIndex:2];
[invocation setArgument:&autoRotate atIndex:3];
[invocation invokeWithTarget:doc];

// Grab the returned print operation.
void *result;
[invocation getReturnValue:&result];

NSPrintOperation *op = (__bridge NSPrintOperation *)result;
[op setShowsPrintPanel:YES];
[op setShowsProgressPanel:YES];
[op runOperation];

这适用于OSX从10.4到10.10(约塞米蒂)。

编辑:您还可以看到this的答案类似,但代码行数较少。

答案 1 :(得分:1)

猜测,由于PDFViewNSView的子类,其指定的初始化程序为-initWithFrame:,而不是-init,因此您对PDFView *pdfView = [[PDFView alloc] init]的调用可能不会允许PDFView设置其初始状态,虽然后续调用它的机器可能会神奇地为你解决这个状态但NSView和子类往往表现得很奇怪(特别是关于绘图)你不使用适当的指定初始值设定项(表示其帧和边界等于NSZeroRect)。

尝试使用-initWithFrame:一些合理的非零矩形。

<强>更新

好吧,只是在黑暗中疯狂拍摄,但是NSPrintOperation的文档说-runOperation阻止了主线程,并建议使用-runOperationModalForWindow:delegate:didRunSelector:contextInfo:来避免完全阻塞主线程。是否有可能通过阻止主线程阻止其他东西进行其初始工作(我称之为未记录的行为或API错误,但是......)?尝试实现模态版本,看看是否有帮助。如果没有,我实际上会向Apple提交一份错误报告。