1

我已经编写了 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];
}

此代码正确滚动表格视图,但它仅为第一页创建 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}}
4

2 回答 2

2

在以编程方式滚动 tableview 后,我最终渲染了持有 tableview 的视图。滚动后渲染表格视图似乎不起作用!

于 2013-07-25T14:31:50.800 回答
0

Your graphics context is initialized with the frame of the UITableView, so it'll always look at the 'first page'. The graphics context for the following 'pages' would need the context offset of the internal UIScrollView of your UITableView. Barring any trickery to access the UIScrollView directly, I suggest you use the [UITableView rectForRowAtIndexPath:] method to get the CGRects of the first and last row you want to draw in the step (i.e. page) and CGRectUnion them to get a rect which will include both (and by that all the rows inbetween).

Edit (as requested in comments): You'd basically replace the rendering message in your loop with something like that

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

And your rendering method would then look like:

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

As to your question about the indexPaths. The indexPath.row will not be always 0-16. They will be 0-16, 17-34, 35-51, etc. This also reflects on your context, i.e. you want to draw the rect for the relevant indexPath rectangle, as this is the 'place' where the layer backing the UITableView has the backing store for the currently rendered graphics. Not knowing your PDF drawing routine, you might need to check your drawing rect there too.

于 2013-07-21T10:49:11.117 回答