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:]
方法来获取你想要在步骤(即页面)中绘制的第一行和最后一行的CGRectUnion
和CGRectUnion
他们得到一个矩形包括(和所有行之间的)。
编辑 (如注释中所要求的):你基本上用你的循环来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。