2013-07-21 95 views
1

我已经撰写了pdfGenerator类来呈现整个UITableView以生成PDF。iOS:将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,但它仅适用于第一页和其余的网页创建PDF来了空白!我不知道为什么会发生这种情况,它应该将当前的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}} 

回答

0

你的图形上下文初始化为UITableView的框架,所以它会经常看“第一页”。以下“页面”的图形上下文需要您的UITableView的内部UIScrollView的上下文偏移量。如果没有任何技巧直接访问UIScrollView,我建议你使用[UITableView rectForRowAtIndexPath:]方法来获取想要在步骤(即页面)中绘制的第一行和最后一行的CGRect,并且它们可以得到一个包含(和通过中间的所有行)。

编辑(的要求,在评论): 你会基本上是在循环使用类似的东西

[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)); 
    //... 
} 

至于你对索引路径的问题。 indexPath.row将不总是0-16。它们将是0-16,17-34,35-51等。这也反映了你的上下文,即你想绘制相关的indexPath矩形的矩形,因为这是'地点',其中支持UITableView有当前渲染图形的后备存储。不知道您的PDF绘图例程,您可能还需要检查您的绘图矩阵。

+0

我不确定你的意思,但是在我的情况下,在滚动tableview之前和之后indexpath总是相同的,即0到16(因为一次总共有17行)。滚动之后,它们也会像重用细胞一样。只是内容会有所不同,这是我感兴趣的内容。我错过了一些吗?你可以通过给出示例代码更加精确。 – applefreak

+0

它给出了相同的结果。请参阅编辑的问题。感谢您对此问题的关注。 – applefreak

1

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

+0

嗨@applefreak你可以发布你的解决方案吗?我有点卡住这个相同的问题! –