I have a custom NSView that I want to print. After setting things up with the NSView and the print options, I make this call:
NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: printView printInfo: printInfo];
[NSPrintOperation setCurrentOperation: printOperation];
[printView beginDocument];
NSGraphicsContext* theContext = printOperation.context;
"theContext" is always nil. If I ignore that, when I make this call:
[printView beginPageInRect: rect atPlacement: location];
I get an exception, saying: "[General] lockFocus/unlockFocus sent to a view which is not in a window"
If I comment that out, I get about a billion messages that say this: "CGContextDrawPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable." Turning on the backtrace just shows all of my drawing is what is causing it.
If I look at the graphics context within my view's "DrawRect:" function:
NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
both graphicsContext and context are nil.
So, what do I have to do to get a valid printing context? I see that there is a NSPrintOperation method createContext, but the docs say not to call it directly, and if I ignore that, it doesn't help and shoots about eight empty jobs to the printer.
Latest version of code, which still results in a null context:
NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: printView printInfo: printInfo];
[printView setCurrentForm: [formSet objectAtIndex: 0]];
NSInteger pageCounter = 0;
formHeight = 0;
formWidth = 0;
for (AFVForm *oneForm in formSet)
{
printView.verticalOffset = formHeight;
NSRect rect = NSMakeRect(0, 0, oneForm.pageWidth, oneForm.pageHeight);
NSPoint location = [printView locationOfPrintRect: rect];
formHeight += [oneForm pageHeight];
if ([oneForm pageWidth] > formWidth)
formWidth = [oneForm pageWidth];
pageCounter++;
printView.currentForm = oneForm;
[printView setPrintMode: YES];
[printView drawRect: NSZeroRect];
[printView setPrintMode: NO];
}
[printOperation setShowsPrintPanel:YES];
[printOperation runOperationModalForWindow: [self window] delegate: nil didRunSelector: nil contextInfo: nil];
beginDocument
andbeginPageInRect:atPlacement:
are called at the beginning of the printing session and at the beginning of each page. Override these methods if you want but don't call them. Don't callsetCurrentOperation
, just create aNSPrintOperation
and callrunOperation
orrunOperationModalForWindow:delegate:didRunSelector:contextInfo:
.See Printing Programming Guide for Mac
Edit, example:
PrintView.h
PrintView.m
somewhere else