使用 AirPrint 在连续卷纸上打印时不需要的额外空白 space

Unwanted extra blank space when printing onto continuous roll of paper using AirPrint

我正在编写使用收据打印机将收据打印到连续纸卷上的代码。收据类似于您在商店使用信用卡付款时收到的收据。

我正在使用 UIMarkupTextPrintFormatter,您可以在下面的代码中看到。

但出于某种原因,我在打印文本的中间和末尾都出现空白 space。 (打印完最后一行后,打印机继续多卷几英寸白纸!)

我检查了 pageCount 属性,它 returns 2,所以可能这就是额外空白 space 的来源。

我还启用了页面范围以显示页数(用于调试)。我不应该在控制器上获取页面范围。但我是,这表明我的内容超过了 2 页。

你能指出我的代码哪里不足吗?将我的 HTML 内容打印到连续纸卷上的正确方法是什么?

我的代码在打印机模拟器上运行完美。我得到了我想要的确切输出。没有意外的空白 space。但它在真正的 AirPrint 兼容收据打印机上失败了!

非常感谢任何建议。

UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
if(!controller){
    DDLogInfo(@"Couldn't get shared UIPrintInteractionController!");
    return;
}

UIPrintInteractionCompletionHandler completionHandler = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
    if(!completed && error)
        DDLogInfo(@"FAILED! due to error in domain %@ with error code %ld", error.domain, (long)error.code);
};

controller.showsPageRange = YES;
controller.showsPaperSelectionForLoadedPapers = YES;

//  Since the we're using a formatter, explicitly set the other properties to nil
controller.printingItem = nil;
controller.printingItems = nil;
controller.printPageRenderer = nil;


UIMarkupTextPrintFormatter *formatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:[self htmlPrintContent]];
formatter.startPage = 0;
formatter.contentInsets = UIEdgeInsetsZero;
controller.printFormatter = formatter;

// Ask for a print job object and configure its settings to tailor the print request
UIPrintInfo *info = [UIPrintInfo printInfo];

// B&W or color, normal quality output for mixed text, graphics, and images
info.outputType = UIPrintInfoOutputGrayscale;

// Select the job named this in the printer queue to cancel our print request.
info.jobName = @"somejobname";

// Make sure we are printing in a portrait orientation.
info.orientation = UIPrintInfoOrientationPortrait;

// We don't need duplex printing so set it to none explicitly
info.duplex = UIPrintInfoDuplexNone;

// Instruct the printing concierge to use our custom print job settings.
controller.printInfo = info;


// Present the standard iOS Print Panel that allows you to pick the target Printer, number of pages, etc.
[controller presentFromRect:self.printButton.frame inView:self.view animated:YES completionHandler:completionHandler];

我最终切换到 UISimpleTextPrintFormatter 而不是 UIMarkupTextPrintFormatter。

所有格式都是使用 NSAttributedString

也实现了

- (CGFloat)printInteractionController:(UIPrintInteractionController *)printInteractionController cutLengthForPaper:(UIPrintPaper *)paper

为了确定我的文字需要的高度。

CGFloat printableWidth = paper.printableRect.size.width;

CGRect attributedStringBoundingRect = [attributedPrintContent boundingRectWithSize:CGSizeMake(printableWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil];

/* Calculate the margins of the roll */
CGFloat lengthOfMargins = paper.paperSize.height - paper.printableRect.size.height;

/* The cut length is the height of the text, plus margins, plus content insets */
CGFloat cutLength = attributedStringBoundingRect.size.height + lengthOfMargins + formatter.contentInsets.bottom + formatter.contentInsets.top;

希望这对您有所帮助...

我发现我在调用boundingRectWithSize:options:context:时还需要从可打印宽度中减去边距。例如:

func printInteractionController(_ printInteractionController: UIPrintInteractionController, cutLengthFor paper: UIPrintPaper) -> CGFloat {
    let size = CGSize(width: paper.printableRect.width - margin * 2, height: 0)

    let boundingRect = attributedText.boundingRect(with: size, options: [
        .usesLineFragmentOrigin,
        .usesFontLeading
    ], context: nil)

    return boundingRect.height + margin * 2
}