Печать вне экрана PDFViews - PullRequest
4 голосов
/ 13 января 2010

У меня есть ситуация, когда я хочу напечатать многостраничный PDF. Хотя я мог использовать служебные классы PDFKit и / или кварцевые функции, чтобы получить информацию для ручного написания кода рисования / нумерации страниц для подкласса NSView, я думал, что более быстрой альтернативой будет создание внеэкранного PDFView и указание напечатать сам , Когда я попробовал это решение, диалоговое окно печати не исчезло, все элементы управления настройками печати в правой половине диалогового окна печати исчезли, и приложение зависло.

Затем я написал крошечное тестовое приложение со следующим методом, который иллюстрирует проблему. Когда тестовая программа компилируется без определенного макроса препроцессора USE_PDF_VIEW, пустое представление отображается нормально. Если определено USE_PDF_VIEW, документ не печатается, большинство элементов управления диалогового окна печати исчезают, а приложение зависает. Хотя у меня есть другие способы достижения своей цели, мне любопытно, почему этот ярлык не работает. Есть ли что-то в рисовании Какао, которого я до сих пор не понимаю? Я врываюсь в Apple Voodoo Magic (tm) за кулисами, которые заставляют PDFView вести себя совершенно иначе, чем другие NSViews?

- (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

}

Ответы [ 4 ]

4 голосов
/ 01 июня 2011

Была такая же проблема. 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 голос
/ 13 января 2010

PDFView является подклассом NSView. Назначенный инициализатор для NSView - -initWithFrame: ... если вы не используете -initWithFrame:, могут произойти странные вещи. Поскольку у PDFView нет других назначенных инициализаторов, -initWithFrame: это так. Я предполагаю, что это как минимум часть вашей проблемы.

Другая часть может быть связана с памятью. Вы используете сборку мусора или нет? Если да, то вы нигде не сохраняете ссылку на свой PDFView, так что, возможно, вас освобождают. Если вы не используете сборщик мусора, вы пропускаете свой PDFView (также потому, что у вас нет ссылок на него, поэтому вы можете освободить его, когда закончите). То же самое с вашим экземпляром myView NSView ... вы пропускаете его, если не используете GC.

0 голосов
/ 12 мая 2017

Мне нравится ответ 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()

}
0 голосов
/ 19 марта 2014

Опираясь на отличный ответ alex-i, я добавил следующие строки, чтобы диалоговое окно печати отображалось в удобном для пользователя месте:

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

Мой self.window предназначен для моего текущего оконного контроллера, а не временного окна.

...