我有一个想要打印的自定义NSView。在使用NSView和打印选项进行设置之后,我进行了以下调用:
NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: printView printInfo: printInfo];
[NSPrintOperation setCurrentOperation: printOperation];
[printView beginDocument];
NSGraphicsContext* theContext = printOperation.context;"theContext“总是为零。如果我忽略这一点,当我打这个电话时:
[printView beginPageInRect: rect atPlacement: location];我得到一个异常,说:"General lockFocus/unlockFocus sent to a view is not a window“
如果我将其注释掉,我会收到大约十亿条消息:"CGContextDrawPath: invalid context 0x0.如果您想要查看回溯,请设置CG_CONTEXT_SHOW_BACKTRACE环境变量。“打开回溯只会显示我的所有绘图都是导致它的原因。
如果我在视图的"DrawRect:“函数中查看图形上下文:
NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];graphicsContext和context都是空的。
那么,我必须做什么才能获得有效的打印上下文呢?我看到有一个NSPrintOperation方法createContext,但是文档说不要直接调用它,如果我忽略它,它就不会有任何帮助,并向打印机发送大约8个空作业。
最新版本的代码,这仍然会导致空上下文:
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];发布于 2019-03-16 06:17:46
beginDocument和beginPageInRect:atPlacement:在打印会话开始时和每页开始时调用。如果需要,可以覆盖这些方法,但不要调用它们。不要调用setCurrentOperation,只需创建一个NSPrintOperation并调用runOperation或runOperationModalForWindow:delegate:didRunSelector:contextInfo:即可。
请参阅Printing Programming Guide for Mac
编辑,示例:
PrintView.h
@interface PrintView : NSView
@property (strong) NSArray *forms;
@endPrintView.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];
}发布于 2019-03-16 08:49:06
在您的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.5x11,因此rectForPage中的常量
letsPrint连接到应用程序菜单的first responder。
https://stackoverflow.com/questions/55191023
复制相似问题