Нежелательное дополнительное пустое пространство при печати на непрерывном рулоне бумаги с использованием AirPrint

Я работаю над кодом, который печатает квитанции на непрерывный рулон бумаги с помощью принтера чеков. Квитанции аналогичны тем, что вы получаете, когда расплачиваетесь кредитной картой в магазине.

Я использую UIMarkupTextPrintFormatter, как вы можете видеть ниже в моем коде.

Но по какой-то причине у меня постоянно появляются пробелы как в середине, так и в конце печатного текста. (После печати последней строки принтер продолжает наматывать еще несколько дюймов чистой бумаги!)

Я проверил свойство pageCount, и оно возвращает 2, так что, вероятно, именно из-за этого появляется дополнительное пустое пространство.

Я также включил диапазон страниц, чтобы показать количество страниц (для отладки). Я не должен получать диапазон страниц на контроллере. Но я да, и это предполагает, что мой контент занимает более 2 страниц.

Не могли бы вы указать, где мой код не соответствует действительности? как правильно распечатать мой HTML-контент на непрерывном рулоне бумаги?

Мой код отлично работает на симуляторе принтера. Я получаю именно тот результат, к которому стремлюсь. Нет неожиданного пустого места. Но это не работает на реальном чековом принтере, совместимом с 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];

person static0886    schedule 05.01.2015    source источник


Ответы (2)


В итоге я переключился на 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;

Надеюсь это поможет...

person static0886    schedule 13.01.2015
comment
Эй, у вас есть пример кода для этого? Я пытаюсь заставить работать длину разреза, и ничего не работает - person Declan Land; 04.02.2019

Я обнаружил, что мне также нужно вычесть поля из ширины печати при вызове 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
}
person Greg Brown    schedule 10.11.2016