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];
beginDocumentandbeginPageInRect: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 aNSPrintOperationand callrunOperationorrunOperationModalForWindow:delegate:didRunSelector:contextInfo:.See Printing Programming Guide for Mac
Edit, example:
PrintView.h
PrintView.m
somewhere else