我们都知道,给手机屏幕做截图很容易,如下面代码
- - (UIImage*) imageWithUIView:(UIView*) view{
- // 创建一个bitmap的context
- // 并把它设置成为当前正在使用的context
- UIGraphicsBeginImageContext(view.bounds.size);
- CGContextRef currnetContext = UIGraphicsGetCurrentContext();
- //[view.layer drawInContext:currnetContext];
- [view.layer renderInContext:currnetContext];
- // 从当前context中创建一个改变大小后的图片
- UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
- // 使当前的context出堆栈
- UIGraphicsEndImageContext();
- return image;
- }
那很多聪明同学就发现,如果对tableView 截图,不就是改变一下里的参数不就行了吗?
- UIGraphicsBeginImageContext(tableView.<span style="color:#ff6666;">contentSize</span>)
我也犯过这样的错误,也曾经天真的以为就是这么easy
那到底如何给UITableView 或 UIScrollView 的content 做截图
1. 给UITableView ,UIScrollView 添加category,让其能顺利的拿到tableView 的一些属性如
numberOfSections,
numberOfRowsInSection
2. 建立一个存放UIImage 的数组screenshots,然后开始对局部进行截图,代码如下
- - (UIImage *)screenshotExcludingHeadersAtSections:(NSSet *)excludedHeaderSections
- excludingFootersAtSections:(NSSet *)excludedFooterSections
- excludingRowsAtIndexPaths:(NSSet *)excludedIndexPaths
- {
- NSMutableArray *screenshots = [NSMutableArray array];
- // Header Screenshot
- UIImage *headerScreenshot = [self screenshotOfHeaderView];
- if (headerScreenshot) [screenshots addObject:headerScreenshot];
- for (int section=0; section<self.numberOfSections; section++) {
- // Header Screenshot
- UIImage *headerScreenshot = [self screenshotOfHeaderViewAtSection:section excludedHeaderSections:excludedHeaderSections];
- if (headerScreenshot) [screenshots addObject:headerScreenshot];
- // Screenshot of every cell of this section
- for (int row=0; row<[self numberOfRowsInSection:section]; row++) {
- NSIndexPath *cellIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
- UIImage *cellScreenshot = [self screenshotOfCellAtIndexPath:cellIndexPath excludedIndexPaths:excludedIndexPaths];
- if (cellScreenshot) [screenshots addObject:cellScreenshot];
- }
- // Footer Screenshot
- UIImage *footerScreenshot = [self screenshotOfFooterViewAtSection:section excludedFooterSections:excludedFooterSections];
- if (footerScreenshot) [screenshots addObject:footerScreenshot];
- }
- UIImage *footerScreenshot = [self screenshotOfFooterView];
- if (footerScreenshot) [screenshots addObject:footerScreenshot];
- return [UIImage <span style="color:#ff6666;">verticalImageFromArray:screenshots</span>];
- }
3. 上面代码中你可能已经看到了,把所有小图拼接成一张大图,思想是先计算所有图加起来的高度,然后便利每张小图用drawPoint 发放在计算起来高度的context上画一张新图
- @implementation UIImage (DHImageFromArrayUtils)
- + (UIImage *)verticalImageFromArray:(NSArray *)imagesArray
- {
- UIImage *unifiedImage = nil;
- CGSize totalImageSize = [self verticalAppendedTotalImageSizeFromImagesArray:imagesArray];
- UIGraphicsBeginImageContextWithOptions(totalImageSize, NO, 0.f);
- // For each image found in the array, create a new big image vertically
- int imageOffsetFactor = 0;
- for (UIImage *img in imagesArray) {
- [img <span style="color:#ff6666;">drawAtPoint:CGPointMake</span>(0, imageOffsetFactor)];
- imageOffsetFactor += img.size.height;
- }
- unifiedImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return unifiedImage;
- }
- + (CGSize)verticalAppendedTotalImageSizeFromImagesArray:(NSArray *)imagesArray
- {
- CGSize totalSize = CGSizeZero;
- for (UIImage *im in imagesArray) {
- CGSize imSize = [im size];
- totalSize.height += imSize.height;
- // The total width is gonna be always the wider found on the array
- totalSize.width = MAX(totalSize.width, imSize.width);
- }
- return totalSize;
- }
那到现在是不是有点明白了,对,就是这么简单,利用tableView scrollRectToVisible 的特性,先在各个小区域截图,存放数组,然后再遍历数组计算小图累计的高度,然后利用drawPoint 重新画大图。