如何给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 重新画大图。

附上源码:源码例子

时间: 2024-11-01 15:01:38

如何给UITableView 或 UIScrollView 的content 做截图的相关文章

使用UIScrollView和UIPageControl做一个可以用手势来切换图片的效果

利用UIScrollView的滚动效果来实现,先上图: 实现过程是:在viewController里先加入UIScrollView和UIPageControl: -(void) loadView { [super loadView]; UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320,480)]; UIPageControl* pageControl = [[UIPageCont

UITableView,UICollectionView,UIScrollView快速返回顶部

UITableView, UICollectionView都继承自UIScrollView,所以可以使用UIScrollView的方法,设置显示内容的偏移量 [self.tableView setContentOffset:CGPointMake(0, 0) animated:YES]; 原文链接http://wpdome.sinaapp.com/?p=189

解决UIScrollView中添加子控件出现“UIScrollView Scrollable Content Size Ambiguity”的办法

来自StackOverflow的帖子,原文见这里. So I just sorted out in this way: Add in the UIScrollView a UIView (we can call that contentView); In this contentView, set top, bottom, left and right margins to 0 (of course from the scrollView which is the superView); Set

UITableView 或 UIScrollView 点击状态栏列表回到顶部

整理来自互联网- 这是tableView继承的scrollView的一个属性 scrollsToTop. 官方说明是这样的: // When the user taps the status bar, the scroll view beneath the touch which is closest to the status bar will be scrolled to top, but only if its `scrollsToTop` property is YES, its del

使用UIScrollView和UIPageControl做一个能够用手势来切换图片的效果

利用UIScrollView的滚动效果来实现,先上图: 实现过程是:在viewController里先增加UIScrollView和UIPageControl: -(void) loadView { [super loadView]; UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320,480)]; UIPageControl* pageControl = [[UIPageCont

让UIScrollView、UITableView的滚动条一直显示

先用xcode5.1.1或更低版本创建一个Category,如图: 然后拷贝以下代码到刚创建的UIImageView+ForScrollView.m文件中: - (void) setAlpha:(float)alpha { if (self.superview.tag == noDisableVerticalScrollTag) { if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin

UIScrollView详解

可能你很难相信,UIScrollView和一个标准的UIView差异并不大,scroll view确实会多一些方法,但这些方法只是UIView一些属性的表面而已.因此,要想弄懂UIScrollView是怎么工作之前,你需要了解 UIView,特别是视图渲染过程的两步. 光栅化和组合 渲染过程的第一部分是众所周知的光栅化,光栅化简单的说就是产生一组绘图指令并且生成一张图片.比如绘制一个圆角矩形.带图片.标题居中的UIButtons.这些图片并没有被绘制到屏幕上去:取而代之的是,他们被自己的视图保持

UIscrollview setcontentoffset

转载  http://blog.csdn.net/nlforever/article/details/9324755 UIscrollview类中 调用setcontentoffset实际上是改变view的坐标原点的位置 画个图解释一下                          content                 frame CGPoint中的x,y分别指的是frame的左上角的content左上角的x,y之差. scrollView的几个属性contentSize.cont

iOS开发——项目实战总结&amp;UITableView性能优化与卡顿问题

UITableView性能优化与卡顿问题 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候,就会堆积很多cell.如果重用cell,为cell创建一个ID 每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell 2.避免cell的重新布局 cell的布局填充等操作 比较耗时,一般创建时就布局好 如可以将cell单独放到一个自定义类,初始化时就布局好