Cocoa osx PDFView NSPrintOperation PrintPanel 不显示页面预览

Posted

技术标签:

【中文标题】Cocoa osx PDFView NSPrintOperation PrintPanel 不显示页面预览【英文标题】:Cocoa osx PDFView NSPrintOperation PrintPanel not showing page preview 【发布时间】:2015-05-06 14:54:36 【问题描述】:

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

我该如何解决这个问题? 请需要帮助。提前致谢。

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

1- 打印面板显示空白页预览。接下来我按节目详情。

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

这是我的代码:

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];

【问题讨论】:

【参考方案1】:

来自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];

这适用于从 10.4 到 10.10 (Yosemite) 的 OSX。

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

【讨论】:

【参考方案2】:

猜测一下,由于PDFViewNSView 的子类,其指定的初始化程序是-initWithFrame:,而不是-init,因此您对PDFView *pdfView = [[PDFView alloc] init] 的调用可能不允许PDFView 设置其初始状态,尽管随后对其机器的调用可能会神奇地为您解决此状态,但NSView 和子类在您不使用正确的指定初始化程序时(尤其是在绘图方面)往往表现得很奇怪(这意味着它的框架和边界是等于NSZeroRect)。

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

更新

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

【讨论】:

感谢您的回答。我尝试使用 initWithFrame 但问题仍然存在:S runOperationModalForWindow 没有帮助 很高兴看到您找到了可行的解决方案 - 为您的答案投票。 :-)

以上是关于Cocoa osx PDFView NSPrintOperation PrintPanel 不显示页面预览的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa PDFView 仅在调整大小时显示 PDF

PDFView osx中的突出显示选择

OSX/Cocoa 的错误代码参考

OSX / Cocoa:获取屏幕中docktile图标的绝对位置[重复]

Objective C - 创建 PDF (Mac OSX / Cocoa)

Qt + CMake for OSX Bundle:Cocoa 平台插件