首页 > 代码库 > 如何给UITableView 或 UIScrollView 的content 做截图

如何给UITableView 或 UIScrollView 的content 做截图

我们都知道,给手机屏幕做截图很容易,如下面代码


- (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 重新画大图。


 

附上源码:源码例子

如何给UITableView 或 UIScrollView 的content 做截图