Контекст NSPrintOperation всегда равен нулю, вызывая сбой.Как мне установить контекст при печати? - PullRequest
0 голосов
/ 16 марта 2019

У меня есть собственный NSView, который я хочу напечатать.После настройки с NSView и опциями печати я делаю этот вызов:

NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: printView printInfo: printInfo];

[NSPrintOperation setCurrentOperation: printOperation];
[printView beginDocument];

NSGraphicsContext* theContext = printOperation.context;

«theContext» всегда равен nil.Если я игнорирую это, когда я делаю этот вызов:

[printView beginPageInRect: rect atPlacement: location];

, я получаю исключение, говоря: «[General] lockFocus / unlockFocus отправлено представлению, которое не находится в окне» *

Если я закомментирую это, я получу около миллиарда сообщений, в которых говорится: «CGContextDrawPath: неверный контекст 0x0. Если вы хотите увидеть обратную трассировку, установите переменную среды CG_CONTEXT_SHOW_BACKTRACE».Включение обратной трассировки просто показывает, что весь мой рисунок вызывает его.

Если я смотрю на графический контекст в функции DrawRect: моего представления:

NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
CGContextRef      context = [[NSGraphicsContext currentContext] graphicsPort];

и graphicsContext, иcontext is nil.

Итак, что мне нужно сделать, чтобы получить действительный контекст печати?Я вижу, что есть метод NSPrintOperation createContext, но в документах говорится, что он не должен вызываться напрямую, и если я его проигнорирую, это не поможет, и он выводит на принтер около восьми пустых заданий.

Последняя версиякод, который все еще приводит к нулевому контексту:

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

Ответы [ 2 ]

0 голосов
/ 16 марта 2019

Пример Swift входит в ваш подкласс NSView.Прошу прощения, если это не поможет:

         func letsPrint() {
             let pInfo = NSPrintInfo.shared
             let d = pInfo.dictionary()
             d["NSLastPage"] = 1
             super.printView(self)
         }
         override func knowsPageRange(_ range: NSRangePointer) -> Bool {
             return true
         }
         override func rectForPage(_ page: Int) -> NSRect {
             if page > 1 { return NSZeroRect }
             return NSRect(x: 0, y: 0, width: 612, height: 792)
         }

В этом примере печатается 1 страница 8,5 x 11, следовательно, константы в rectForPage

letsPrint подключены к меню первого респондента меню приложения.

0 голосов
/ 16 марта 2019

beginDocument и beginPageInRect:atPlacement: вызываются в начале сеанса печати и в начале каждой страницы.Переопределите эти методы, если хотите, но не вызывайте их.Не звоните setCurrentOperation, просто создайте NSPrintOperation и звоните runOperation или runOperationModalForWindow:delegate:didRunSelector:contextInfo:.

См. Печать руководства по программированию для Mac

Редактировать,пример:

PrintView.h

@interface PrintView : NSView

@property (strong) NSArray *forms;

@end

PrintView.m

@interface PrintView ()

@property (weak) NSTextField *titleField;
@property (weak) NSDictionary *currentForm;

@end


@implementation PrintView

- (instancetype)initWithFrame:(NSRect)frameRect {
    if (self = [super initWithFrame:frameRect]) {
        // add a title text field
        NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(25.0, 225.0, 250.0, 25.0)];
        textField.alignment = NSTextAlignmentCenter;
        [self addSubview:textField];
        self.titleField = textField;
    }
    return self;
}

- (BOOL)knowsPageRange:(NSRangePointer)range {
    range->location = 1;
    range->length = self.forms.count;
    return YES;
}

- (NSRect)rectForPage:(NSInteger)page {
    return self.bounds;
}

- (void)beginPageInRect:(NSRect)rect atPlacement:(NSPoint)location {
    [super beginPageInRect:rect atPlacement:location];
    NSPrintOperation *printOperation = [NSPrintOperation currentOperation];
    self.currentForm = self.forms[printOperation.currentPage - 1];
    // set the title
    [self.titleField setStringValue:
        [NSString stringWithFormat:@"Form ‘%@’ page %li",
            self.currentForm[@"title"], (long)printOperation.currentPage]];
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    // Drawing code here.
    // draw a colored frame
    NSColor *formColor = self.currentForm[@"color"];
    NSRect rect = self.bounds;
    NSInsetRect(rect, 20.0, 20.0);
    [formColor set];
    NSFrameRect(rect);
}

@end

где-то еще

- (IBAction)printAction:(id)sender {
    PrintView *printView = [[PrintView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300.0, 300.0)];
    printView.forms = @[
            @{@"title":@"Form A", @"color":[NSColor redColor]},
            @{@"title":@"Form B", @"color":[NSColor greenColor]},
            @{@"title":@"Form C", @"color":[NSColor blueColor]},
        ];
    NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:printView];
    [printOperation setShowsPrintPanel:YES];
    [printOperation runOperationModalForWindow:[self window] delegate:nil didRunSelector:NULL contextInfo:NULL];
}
...