iOS:将UITableView呈现为PDF

我已经写了pdfGenerator类来呈现整个UITableView来生成PDF。

用法:

[pdfGenerator createPDFFromTableview:self.tableView]; 

类方法:

 - (void)createPDFFromTableview:(UITableView *)tableview { [tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self renderTableView:tableview]; int rows = [tableview numberOfRowsInSection:0]; int numberofRowsInView = 17; for (int i = 0; i < rows/numberofRowsInView; i++) { [tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(i+1)*numberofRowsInView inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self renderTableView:tableview]; } } - (void)renderTableView:(UITableView*)tableview { UIGraphicsBeginImageContext(tableview.frame.size); [tableview.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *tableviewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIGraphicsBeginPDFPage(); [tableviewImage drawInRect:tableview.frame]; } 

此代码正确滚动tableview,但它只为第一页创buildPDF, 其余的页面将空白! 我不知道为什么它发生,而应该采取当前的uitableview快照和呈现,但它似乎这样做只为第一页。 有人能指出这里可能是错的吗? 有没有更好的办法来做我想达到的目标?

[编辑]

以下给出了相同的结果;

 int totalRows = [tableview numberOfRowsInSection:0]; int totalVisibleRows = 17; for (int i = 0; i < ceil((float)totalRows/totalVisibleRows); i++) { [tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i * totalVisibleRows inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [pdfGenerator renderTableView:tableview indexPathStart:[NSIndexPath indexPathForRow:i * totalVisibleRows inSection:0] indexPathEnd:[[tableview indexPathsForVisibleRows] lastObject]]; } - (void)renderTableView:(UITableView*)tableview indexPathStart:(NSIndexPath *)startingIndexPath indexPathEnd:(NSIndexPath *)endIndexPath { CGRect rectToDraw = CGRectUnion([tableview rectForRowAtIndexPath:startingIndexPath], [tableview rectForRowAtIndexPath:endIndexPath]); NSLog(@"%@", NSStringFromCGRect(rectToDraw)); UIGraphicsBeginImageContext(rectToDraw.size); [tableview.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *tableviewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIGraphicsBeginPDFPage(); [tableviewImage drawInRect:rectToDraw]; } 

输出rectToDraw:

 {{0, 0}, {768, 720}} {{0, 680}, {768, 720}} {{0, 1360}, {768, 720}} {{0, 2040}, {768, 360}} 

我最终以编程方式滚动tableview后呈现的是持有tableview的视图。 渲染tableview似乎没有工作后滚动!

你的graphics上下文是用UITableView的框架初始化的,所以它会一直看着'第一页'。 以下“页面”的graphics上下文将需要UITableView的内部UIScrollView的上下文偏移量。 除了任何欺骗,直接访问UIScrollView,我build议你使用[UITableView rectForRowAtIndexPath:]方法来获取你想要在步骤(即页面)中绘制的第一行和最后一行的CGRectUnionCGRectUnion他们得到一个矩形包括(和所有行之间的)。

编辑 (如注释中所要求的):你基本上用你的循环来replace渲染消息

 [self renderTableView:tableview indexPathStart:[NSIndexPath indexPathForRow:row inSection:0] indexPathEnd:[[tableview indexPathsForVisibleRows] lastObject]]; 

然后你的渲染方法将如下所示:

 - (void)renderTableView:(UITableView*)tableview indexPathStart:(NSIndexPath *)startingIndexPath indexPathEnd:(NSIndexPath *)endIndexPath{ CGRect rectToDraw = CGRectUnion([tableview rectForRowAtIndexPath:startingIndexPath], [tableview rectForRowAtIndexPath:endIndexPath]); NSLog(@"%@", NSStringFromCGRect(rectToDraw)); //... } 

至于你有关indexPaths的问题。 indexPath.row不会总是0-16。 它们将是0-16,17-34,35-51等。这也反映了你的上下文,即你想绘制相关的indexPath矩形的矩形,因为这是“地方”的地方支持UITableView有当前渲染graphics的后备存储。 不知道你的PDF绘图程序,你可能还需要检查你的绘图rect。