使用场景:

本人在自定义UITabBarController的时候,想要实现手势滑动返回上一页面的效果,也就是仿QQ的滑动返回,这种滑动返回是基于UIPanGestureRecognizer这一手势,实现原理是在导航条Push的时候截取当前屏幕,并把截取到的图片添加的Window的视图上,让后当启用滑动手势的时候只要把当前(Push到的)视图滑动开来,就可以看到之前截取到的倾慕快照,当返回上一页面的时候再把截取的图片从Window上移除即可。遇到的问题是:小编自定义的UITabBarController是继承于UIViewControler,而不是系统的UITabBarController,底部的按钮区域是一个View,截取屏幕的时候总是不能截取到按钮区域的View;这就是第一种截屏方法,而后通过查找资料找到一种能够解决此问题的方法,也就是第二种截屏方法。

第一种截屏方法:

//获取截屏图片
- (UIImage *)getCurrentScreenShot{UIGraphicsBeginImageContextWithOptions([[[UIApplication sharedApplication] keyWindow] bounds].size, NO, 0.0);[[[UIApplication sharedApplication] keyWindow].layer renderInContext:UIGraphicsGetCurrentContext()];UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return image;
}

注:第一种截图方法适合于屏幕上只有一个View的时候,效率较高,一般场景下就够用了。原理是首先创建一个和主屏幕(KeyWindow)一样大小的画布,然后通过renderInContext方法把屏幕图层上的内容绘制到画布上,然后根据这张画布生成图片即可。


第二种截屏方法:

//截取全屏视图
-(UIImage *)getImageWithFullScreenshot
{UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;CGSize imageSize = CGSizeZero;//适配横屏状态if (UIInterfaceOrientationIsPortrait(orientation) )imageSize = [UIScreen mainScreen].bounds.size;elseimageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);UIGraphicsBeginImageContextWithOptions(imageSize, NO, [UIScreen mainScreen].scale);CGContextRef context = UIGraphicsGetCurrentContext();for (UIWindow *window in [[UIApplication sharedApplication] windows]){CGContextSaveGState(context);CGContextTranslateCTM(context, window.center.x, window.center.y);CGContextConcatCTM(context, window.transform);CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);// Correct for the screen orientationif(orientation == UIInterfaceOrientationLandscapeLeft){CGContextRotateCTM(context, (CGFloat)M_PI_2);CGContextTranslateCTM(context, 0, -imageSize.width);}else if(orientation == UIInterfaceOrientationLandscapeRight){CGContextRotateCTM(context, (CGFloat)-M_PI_2);CGContextTranslateCTM(context, -imageSize.height, 0);}else if(orientation == UIInterfaceOrientationPortraitUpsideDown){CGContextRotateCTM(context, (CGFloat)M_PI);CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);}if([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:NO];else[window.layer renderInContext:UIGraphicsGetCurrentContext()];CGContextRestoreGState(context);}UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return image;
}

注:第二种截屏方法适用于屏幕上有多个视图的场景,原理基本和第一种方法一样,只是第二种方法不仅会绘制主屏幕的视图,它还会遍历已存在的所有window,并拼接所得到的画布。


附:此两种方法是适用于iOS 7及以后版本,除此之外还有一些过期的方法和私有API,小编是不建议使用的,在此也就不再粘贴代码,如有问题可留言告知,多谢!