当桌面视图太大而无法放在屏幕上时,打印它们的所有行

use*_*996 0 printing uitableview ios

如何打印整个多页UITableView(我需要滚动)而不仅仅是当前显示在屏幕上的视图部分?

rob*_*off 14

我假设您正在谈论使用iOS打印系统进行打印,如" iOS绘图和打印指南 "的"打印"一章中所述.

既然-[UITableView viewPrintFormatter]没有返回可用UIViewPrintFormatter,你必须找到另一种方法来做到这一点.让我们编写一个将表视图转换为PDF的函数:

static NSData *pdfDataWithTableView(UITableView *tableView) {
Run Code Online (Sandbox Code Playgroud)

首先,我们将保存视图的当前边界,因此我们可以在最后恢复边界.

    CGRect priorBounds = tableView.bounds;
Run Code Online (Sandbox Code Playgroud)

现在我们将要求表视图计算出适合所有行的高度.

    CGSize fittedSize = [tableView sizeThatFits:CGSizeMake(priorBounds.size.width, HUGE_VALF)];
Run Code Online (Sandbox Code Playgroud)

我们将继续调整表视图的大小.我们还将其原点(与其相同contentOffset)设置为0,0因此它实际上将包含其所有行.

    tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height);
Run Code Online (Sandbox Code Playgroud)

我们需要一个CGRect包含PDF页面边界的内容.

    // Standard US Letter dimensions 8.5" x 11"
    CGRect pdfPageBounds = CGRectMake(0, 0, 612, 792);
Run Code Online (Sandbox Code Playgroud)

现在我们可以创建一个PDF图形上下文.

    NSMutableData *pdfData = [[NSMutableData alloc] init];
    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil); {
Run Code Online (Sandbox Code Playgroud)

我们需要将表视图渲染到图形上下文中.由于表格视图可能比页面大小更高,因此我们以页面高度的增量向下沿Y轴逐步调整上下文的原点.

        for (CGFloat pageOriginY = 0; pageOriginY < fittedSize.height; pageOriginY += pdfPageBounds.size.height) {
Run Code Online (Sandbox Code Playgroud)

我们告诉上下文开始一个页面.

            UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil);
Run Code Online (Sandbox Code Playgroud)

由于我们要更改上下文的来源,我们将保存图形状态并在呈现此页面后恢复它.

            CGContextSaveGState(UIGraphicsGetCurrentContext()); {
Run Code Online (Sandbox Code Playgroud)

现在我们可以调整上下文的原点,使渲染区域的左上角位于表视图坐标系中的适当位置.

                CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);
Run Code Online (Sandbox Code Playgroud)

最后,我们可以告诉表视图的层将其自身呈现给上下文.当前页面边界之外的所有内容都将被剪掉.

                [tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
Run Code Online (Sandbox Code Playgroud)

要清理,我们恢复图形状态.

            } CGContextRestoreGState(UIGraphicsGetCurrentContext());
Run Code Online (Sandbox Code Playgroud)

此时,如果有更多页面,我们将回到for循环的顶部.

        }
Run Code Online (Sandbox Code Playgroud)

现在我们已经渲染了所有页面,因此我们可以结束PDF图形上下文.

    } UIGraphicsEndPDFContext();
Run Code Online (Sandbox Code Playgroud)

我们需要恢复表视图的边界.

    tableView.bounds = priorBounds;
Run Code Online (Sandbox Code Playgroud)

最后我们可以返回PDF数据.

    return pdfData;
}
Run Code Online (Sandbox Code Playgroud)

这一切都在一起:

static NSData *pdfDataWithTableView(UITableView *tableView) {
    CGRect priorBounds = tableView.bounds;
    CGSize fittedSize = [tableView sizeThatFits:CGSizeMake(priorBounds.size.width, HUGE_VALF)];
    tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height);

    // Standard US Letter dimensions 8.5" x 11"
    CGRect pdfPageBounds = CGRectMake(0, 0, 612, 792);

    NSMutableData *pdfData = [[NSMutableData alloc] init];
    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil); {
        for (CGFloat pageOriginY = 0; pageOriginY < fittedSize.height; pageOriginY += pdfPageBounds.size.height) {
            UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil);
            CGContextSaveGState(UIGraphicsGetCurrentContext()); {
                CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);
                [tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
            } CGContextRestoreGState(UIGraphicsGetCurrentContext());
        }
    } UIGraphicsEndPDFContext();
    tableView.bounds = priorBounds;
    return pdfData;
}
Run Code Online (Sandbox Code Playgroud)

你当然可以使用它UIGraphicsBeginPDFContextToFile.这会减少工作记忆.

无论哪种方式,一旦您拥有PDF(在内存或文件中),您就可以使用iOS打印系统将其发送到打印机.

  • 我试过你的代码 - 可以打印表格视图的可见内容。但假设它有 100 行,20 行可见,25 行适合一页,然后我打印了 20 行。第一页的其余部分和第 2 页直到结尾都是空白的。表格视图单元格是可重用的,因此如果它们不可见,它们就没有任何内容。这里有什么解决方法吗? (2认同)