【问题标题】:Printing Off-screen PDFViews打印离屏 PDF 视图
【发布时间】:2011-01-04 17:39:23
【问题描述】:

我想打印多页 PDF。虽然我可以使用 PDFKit 实用程序类和/或石英函数来获取信息以手动为 NSView 子类编写绘图/分页代码,但我认为更快的替代方法是创建一个屏幕外 PDFView 并告诉它自己打印.当我尝试这个解决方案时,打印对话框并没有消失,打印对话框右半部分的所有打印设置控件都消失了,应用程序冻结了。

然后我使用以下方法编写了一个小型测试应用程序来说明问题。在未定义 USE_PDF_VIEW 预处理器宏的情况下编译测试程序时,空白视图显示正常。如果定义了 USE_PDF_VIEW,则不会打印文档,大多数打印对话框控件都会消失,并且应用程序会冻结。虽然我有其他方法可以实现我的目标,但我很好奇为什么这条捷径不起作用。可可绘画有什么我仍然不明白的地方吗?我是否在幕后猛烈抨击 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

}

【问题讨论】:

  • 我遇到了完全相同的问题。你找到解决方案了吗?

标签: objective-c cocoa pdf pdfkit


【解决方案1】:

遇到了完全相同的问题。 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];

【讨论】:

  • 完美,非常感谢!作为 OP,我遇到了确切的问题,这对我来说完美地解决了。
【解决方案2】:

在 alex-i 的出色答案的基础上,我添加了以下几行,以便打印对话框显示在用户友好的位置:

NSRect windowRect = self.window.frame;
NSPoint printTopLeftPoint = NSMakePoint(CGRectGetMidX(windowRect), CGRectGetMaxY(windowRect));
[wnd setFrameTopLeftPoint:printTopLeftPoint];

我的self.window 用于我当前的窗口控制器,而不是临时窗口。

【讨论】:

    【解决方案3】:

    我喜欢 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()
    
    }
    

    【讨论】:

    • 这对我来说是最好的解决方案。将它添加到子视图并使 alpha 0.0 对我来说非常有效。因此,将使用活动窗口。
    【解决方案4】:

    PDFView 是 NSView 的子类。 NSView 的指定初始化程序是-initWithFrame: ...如果您不使用-initWithFrame:,可能会发生奇怪的事情。由于 PDFView 没有其他指定的初始化程序,-initWithFrame: 就是它。我猜这至少是你问题的一部分。

    另一部分可能与内存有关。您是否使用垃圾收集?如果是,您不会在任何地方保留对 PDFView 的引用,因此可能会被释放。如果您没有使用垃圾收集,那么您正在泄漏您的 PDFView(也因为您没有保留对它的引用,因此您可以在完成后释放它)。与您的 myView NSView 实例相同...如果您不使用 GC,则会泄漏它。

    【讨论】:

    • 不,我有同样的问题,而且 NSView 确实有一个直接的 init 方法...... initWithFrame 没有任何帮助。另外,我不确定 Waldo,但我会保留所有东西,直到我不再需要它...
    猜你喜欢
    • 1970-01-01
    • 2012-09-23
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    相关资源
    最近更新 更多