我们都知道,给手机屏幕做截图很容易,如下面代码
- (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 重新画大图。
附上源码:源码例子