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

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

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

由于-[UITableView viewPrintFormatter]不返回可用的UIViewPrintFormatter ,因此您必须找到另一种方法。 让我们编写一个将表视图转换为PDF的函数:

 static NSData *pdfDataWithTableView(UITableView *tableView) { 

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

  CGRect priorBounds = tableView.bounds; 

现在我们将要求表格视图确定适合其所有行的高度。

  CGSize fittedSize = [tableView sizeThatFits:CGSizeMake(priorBounds.size.width, HUGE_VALF)]; 

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

  tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height); 

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

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

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

  NSMutableData *pdfData = [[NSMutableData alloc] init]; UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil); { 

我们需要将表视图呈现到图形上下文中。 由于表格视图可能高于页面大小,因此我们以页面高度的增量向下沿Y轴逐步显示上下文的原点。

  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()); 

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

  } 

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

  } UIGraphicsEndPDFContext(); 

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

  tableView.bounds = priorBounds; 

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

  return pdfData; } 

这一切都在一起:

 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; } 

您当然可以使用UIGraphicsBeginPDFContextToFile 。 这会减少工作记忆。

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