2010-01-13 4 views
4

Je suis dans une situation dans laquelle je souhaite imprimer un document PDF de plusieurs pages. Alors que je pouvais utiliser les classes d'utilitaires PDFKit et/ou les fonctions quartz pour obtenir les informations pour écrire manuellement le code de dessin/pagination pour une sous-classe NSView, je pensais que l'alternative serait de créer un PDFView hors écran et de lui imprimer . Lorsque j'ai essayé cette solution, la boîte de dialogue d'impression n'a pas disparu, tous les contrôles des paramètres d'impression dans la moitié droite de la boîte de dialogue d'impression ont disparu et l'application s'est figée. J'ai ensuite écrit une petite application de test avec la méthode suivante qui illustre le problème. Lorsque le programme de test est compilé sans la macro préprocesseur USE_PDF_VIEW définie, la vue vide s'affiche correctement. Si USE_PDF_VIEW est défini, le document ne s'imprime pas, la plupart des contrôles de dialogue d'impression disparaissent et l'application se bloque. Alors que j'ai d'autres moyens d'atteindre mon objectif, je suis curieux de savoir pourquoi ce raccourci ne fonctionne pas. Y at-il quelque chose à propos de dessin Cocoa je ne comprends toujours pas? Est-ce que je tape sur Apple Voodoo Magic (tm) derrière les scènes qui font que PDFView se comporte d'une manière complètement différente des autres NSViews?Impression de PDFViews hors écran

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

Je vais avoir exactement le même problème. Avez-vous déjà trouvé une solution? –

Répondre

1

PDFView est une sous-classe de NSView. L'initialiseur désigné pour NSView est -initWithFrame: ... si vous n'utilisez pas -initWithFrame: des choses étranges peuvent arriver. Puisque PDFView n'a pas d'autres initialiseurs désignés, c'est le -initWithFrame:. Je suppose que c'est au moins une partie de votre problème.

Une autre partie peut être liée à la mémoire. Utilisez-vous la collecte des ordures ou non? Si vous l'êtes, vous ne gardez nulle part une référence à votre PDFView, vous risquez donc d'être désalloué. Si vous n'utilisez pas le garbage collection, vous fuyez votre PDFView (également parce que vous n'y conservez aucune référence, vous pouvez donc le relâcher lorsque vous avez terminé). Pareil avec votre instance myView NSView ... vous le fuyez si vous n'utilisez pas le GC.

+0

Non, j'ai le même problème, et NSView a une méthode d'initialisation directe ... initWithFrame n'a pas aidé. Aussi, je ne suis pas sûr de Waldo, mais je retiens tout jusqu'à ce que je n'en aie plus besoin ... –

4

Avait exactement le même problème. Le PDFView doit être ajouté à un NSWindow pour que printWithInfo:autoRotate: fonctionne (au moins dans mon cas), sinon les contrôles d'impression seront vides ou ne fonctionneront pas.

Voici le code complet:

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

Parfait, merci beaucoup! J'avais le problème exact comme OP et cela a résolu le problème parfaitement pour moi. –

0

bâtiment sur alex-i excellente réponse, j'ai ajouté les lignes suivantes de sorte que le dialogue d'impression est présenté dans un endroit convivial:

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

Mon self.window est pour mon contrôleur de fenêtre en cours, pas la fenêtre temporaire.

0

J'aime la réponse d'alex-i parce qu'elle n'utilise pas d'API privées. Mais dans mon cas, j'ai déjà une fenêtre (et je suppose que dans la plupart des cas vous le feriez!), Alors j'ai pensé que j'utiliserais cette fenêtre au lieu d'en créer une. Voici ce que je fini par faire, en utilisant rapide:

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

} 
Questions connexes