我遇到要打印多页PDF的情况。虽然我可以使用PDFKit实用程序类和/或石英函数来获取手动编写NSView子类的绘图/分页代码的信息,但我认为更快的替代方法是创建一个屏幕外的PDFView并告诉它自己打印。当我尝试这个解决方案时,打印对话框没有消失,打印对话框右半部分的所有打印设置控件都消失了,应用程序冻结了。
然后我用以下方法编写了一个很小的测试应用程序来说明问题。在未定义USE_PDF_VIEW预处理器宏的情况下编译测试程序时,空白视图显示正常。如果定义了USE_PDF_VIEW,则文档不会打印,大多数打印对话框控件都会消失,并且应用程序会冻结。虽然我有其他方法来实现我的目标,但我很好奇为什么这个快捷方式不起作用。关于Cocoa绘画有什么我还不明白吗?我是否在幕后使用Apple Voodoo Magic(tm),这使得PDFView的行为方式与其他NSView完全不同?
- (void)printMyStuff:(id)sender {
NSPrintInfo *currInfo = [NSPrintInfo sharedPrintInfo];
#ifdef USE_PDF_VIEW
PDFView *pdfView = [[PDFView alloc] init];
PDFDocument *pdfDoc = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:@"/Users/wls/Documents/my_document.pdf"]];
[pdfView setDocument: pdfDoc];
[pdfView printWithInfo:currInfo autoRotate:YES];
#else
NSView *myView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 500, 500)];
NSPrintOperation *myop = [NSPrintOperation printOperationWithView:myView printInfo:currInfo];
[myop runOperation];
#endif
}
答案 0 :(得分:4)
有完全相同的问题。
需要将PDFView
添加到NSWindow
才能使printWithInfo:autoRotate:
正常工作(至少在我的情况下),否则打印控件将变为空白或无效。
这是完整的代码:
PDFView *vDoc = [[PDFView alloc] init];
[vDoc setDocument:pdfDoc];
[vDoc setAutoScales: YES];
[vDoc setDisplaysPageBreaks: NO];
NSWindow *wnd = [[NSWindow alloc] init];
[wnd setContentSize:vDoc.frame.size];
[wnd setContentView:vDoc];
[vDoc printWithInfo:printInfo autoRotate:YES];
[wnd release];
[vDoc release];
答案 1 :(得分:1)
PDFView是NSView的子类。 NSView的指定初始化程序为-initWithFrame:
...如果您不使用-initWithFrame:
,可能会发生奇怪的事情。由于PDFView没有其他指定的初始化程序,-initWithFrame:
就是它。我猜这至少是你问题的一部分。
另一部分可能与记忆有关。你在使用垃圾收集吗?如果您是,那么您不会在任何地方保留对PDFView的引用,因此可能会被取消分配。如果您没有使用垃圾收集,那么您正在泄露PDFView(也因为您没有引用它,所以您可以在完成后释放它)。与myView NSView实例相同...如果您不使用GC,则会泄漏它。
答案 2 :(得分:0)
基于alex-i的优秀答案,我添加了以下行,以便打印对话框显示在用户友好的位置:
NSRect windowRect = self.window.frame;
NSPoint printTopLeftPoint = NSMakePoint(CGRectGetMidX(windowRect), CGRectGetMaxY(windowRect));
[wnd setFrameTopLeftPoint:printTopLeftPoint];
我的self.window
用于我当前的窗口控制器,而不是临时窗口。
答案 3 :(得分:0)
我喜欢alex-i的答案,因为它不使用私有API。但在我的情况下,我已经有了一个窗口(我想在大多数情况下你会这样做!),所以我想我会使用那个窗口而不是创建一个窗口。以下是我最终使用swift进行的操作:
func print(_ pdfDocument: PDFDocument, using window: NSWindow) {
// create a hidden pdf view with the document
let pdfView = PDFView()
pdfView.document = pdfDocument
pdfView.autoScales = true
pdfView.displaysPageBreaks = false
pdfView.frame = NSMakeRect(0.0, 0.0, 50.0, 50.0)
pdfView.isHidden = true
// add the view to the window and print
window.contentView.addSubview(pdfView)
pdfView.print(nil)
pdfView.removeFromSuperview()
}