How do I print my whole multi-page UITableView
(I need to scroll) and not just the part of the view which is currently displayed on screen?
1 回答
我假设您正在谈论使用 iOS 打印系统进行打印,如 iOS绘图和打印指南的“打印”一章中所述。
由于-[UITableView viewPrintFormatter]
不返回一个可用的UIViewPrintFormatter
,你必须找到另一种方法来做到这一点。让我们编写一个将表格视图转换为 PDF 的函数:
static NSData *pdfDataWithTableView(UITableView *tableView) {
首先,我们将保存视图的当前边界,以便在最后恢复边界。
CGRect priorBounds = tableView.bounds;
现在我们将要求 table view 计算出它需要多高才能容纳它的所有行。
CGSize fittedSize = [tableView sizeThatFits:CGSizeMake(priorBounds.size.width, HUGE_VALF)];
我们将继续将表格视图调整为那么大。我们还将它的原点(与它的 相同contentOffset
)设置为 0,0,因此它实际上将包含它的所有行。
tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height);
我们需要一个CGRect
包含 PDF 页面边界的文件。
// 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);
最后,我们可以告诉 table view 的 layer 将自己渲染到上下文中。当前页面范围之外的所有内容都将被剪掉。
[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 打印系统将其发送到打印机。