首页 > 解决方案 > 将 NSView 打印到 PDF 无法按预期工作

问题描述

我用 NSPrintOperation 方法在 PDF 中转换了一个 NSView (PDFContentView:NSView)。此 NSView 包含 2 个子视图(绘图:NSView)。这个子视图是使用 drawRect 方法绘制的。

当我在 NSWindow 中显示我的视图时,预期的结果是正确的:

在此处输入图像描述

但在 PDF 文件中,第二个子视图似乎包含在第一个子视图中:

在此处输入图像描述

这似乎是层的问题,但是当我将 setWantsLayer: 更改为 NO 时,结果相同。

注意:我找到了建议将通过 drawRect 方法绘制的子视图转换为 NSImage 然后将其添加到视图的答案。但是这个解决方案不适合我的问题,因为我需要保持在不像素化子视图的情况下放大 pdf 的可能性。

谢谢您的帮助。

这是我的代码:

将我的 pdfContentView 转换为 PDF 的方法:

- (void)createPDFWithPages
{
    NSPrintInfo *printInfo;
    NSPrintInfo *sharedInfo;
    NSPrintOperation *printOp;
    NSMutableDictionary *printInfoDict;
    NSMutableDictionary *sharedDict;

    sharedInfo = [NSPrintInfo sharedPrintInfo];
    sharedDict = [sharedInfo dictionary];
    printInfoDict = [NSMutableDictionary dictionaryWithDictionary:sharedDict];

    [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *desktopURLArray = [fileManager URLsForDirectory:NSDesktopDirectory inDomains:NSUserDomainMask];
    NSURL *desktopURL = [desktopURLArray objectAtIndex:0];
    NSString *fileName = [NSString stringWithFormat:@"/%@", @"myPDF.pdf"];
    NSURL *fileURL = [NSURL fileURLWithPath:[[desktopURL path] stringByAppendingString:fileName]];

    [printInfoDict setObject:[fileURL path] forKey:NSPrintSavePath];

    printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
    [printInfo setTopMargin:30.0];
    [printInfo setBottomMargin:30.0];
    [printInfo setLeftMargin:30.0];
    [printInfo setRightMargin:30.0];
    [printInfo setHorizontalPagination: NSAutoPagination];
    [printInfo setVerticalPagination: NSAutoPagination];
    [printInfo setVerticallyCentered:NO];

    printOp = [NSPrintOperation printOperationWithView:pdfContentView printInfo:printInfo];

    [printOp setShowsPrintPanel:NO];
    [printOp runOperation];
}

PDFContentView.m:

#import "PDFContentView.h"
#import "Drawing.h"

@interface PDFContentView ()
{
    Drawing *drawing1;
    Drawing *drawing2;
}
@end

@implementation PDFContentView

- (id)init
{
    if(self = [super init])
    {
        self.frame = NSMakeRect(10, 10, 520, 780); //page size = (520, 780)
        [self setWantsLayer:YES];
        self.layer.backgroundColor = [NSColor whiteColor].CGColor;

        drawing1 = [[Drawing alloc] initWithFrame:NSMakeRect(0, 20, 50, 50)];
        [drawing1 setBackgroundColor:[NSColor greenColor]];
        [self addSubview:drawing1];

        drawing2 = [[Drawing alloc] initWithFrame:NSMakeRect(30, 0, 50, 50)];
        [drawing2 setBackgroundColor:[NSColor yellowColor]];
        [self addSubview:drawing2];
    }

    return self;
}

- (BOOL)isFlipped
{
    return YES;
}

@end

绘图.m:

#import "Drawing.h"

@interface Drawing ()
{
    NSColor *backgrounColor;
}
@end

@implementation Drawing

- (id)initWithFrame:(NSRect)contentRect
{
    if(self = [super initWithFrame:(NSRect)contentRect])
    {
        self.frame = contentRect;
        [self setWantsLayer:YES];

        backgrounColor = [[NSColor alloc] init];
        backgrounColor = [NSColor colorWithCalibratedRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:255.0/255.0];
    }

    return self;
}

- (BOOL)isFlipped
{
    return YES;
}

- (void)setBackgroundColor:(NSColor*)color;
{
    backgrounColor = color;

    [self setNeedsDisplay:YES];
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];

    CGMutablePathRef path00 = CGPathCreateMutable();

    CGPathMoveToPoint(path00, NULL, 0, 0);
    CGPathAddLineToPoint(path00, NULL, self.frame.size.width, 0);
    CGPathAddLineToPoint(path00, NULL, self.frame.size.width, self.frame.size.height);
    CGPathAddLineToPoint(path00, NULL, 0, self.frame.size.height);
    CGPathCloseSubpath(path00);

    CGContextSaveGState(context);
    CGContextAddPath(context, path00);
    CGContextSetFillColorWithColor(context, backgrounColor.CGColor);
    CGContextFillPath(context);
    CGContextRestoreGState(context);


    CGRect borderRect = NSMakeRect(0.5, 0.5, 24, 24);
    CGMutablePathRef borderPath = CGPathCreateMutable();
    CGPathAddRect(borderPath, NULL, borderRect);
    CGPathCloseSubpath(borderPath);

    CGContextSaveGState(context);
    CGContextAddPath(context, borderPath);
    CGContextSetStrokeColorWithColor(context, [NSColor redColor].CGColor);
    CGContextSetLineWidth(context, 1);
    CGContextStrokePath(context);
    CGContextRestoreGState(context); // => Missing funtion

    CGMutablePathRef path2 = CGPathCreateMutable();
    CGRect aRect = NSMakeRect(10, 11, 4, 4);
    CGPathAddRect(path2, NULL, aRect);
    CGPathCloseSubpath(path2);

    CGContextSaveGState(context);
    CGContextAddPath(context, path2);
    CGContextSetShouldAntialias(context, NO);
    CGContextSetStrokeColorWithColor(context, [NSColor blueColor].CGColor);
    CGContextSetLineWidth(context, 1);
    CGContextStrokePath(context);
    CGContextRestoreGState(context); // => Missing funtion
}

@end

标签: pdflayernsviewdrawrectnsprintoperation

解决方案


推荐阅读