需求描述:
有两个ViewController 我们记做 A、B ,其中B controller只是显示下半部分;
如下图效果:
实现这种的方案很多,可以用添加View方法, 也可以用UIWindows 来实现。
但是我这边是想用presentViewController 实现,但是A present B之后,之前的A就会消失,不会和B 覆盖显示,因此就相当了截取A试图之后在present B。
具体看看实现方案吧:
方法一:直接截屏当前视图
这个方法获取的到图片不会失真
1 -(UIImage *)captureImageFromViewLow:(UIView *)orgView { 2 //获取指定View的图片 3 UIGraphicsBeginImageContextWithOptions(orgView.bounds.size, NO, 0.0); 4 CGContextRef context = UIGraphicsGetCurrentContext(); 5 [orgView.layer renderInContext:context]; 6 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 7 UIGraphicsEndImageContext(); 8 return image; 9 }
方法二:获取当前window 层截图(当然在webView情况下是没法截图的)
/** 全屏截图方法 @return 获取指定View 的截屏结果 */ -(UIImage *)fullScreenImage{ UIWindow *windows = [UIApplication sharedApplication].keyWindow; CGFloat scale = ([UIScreen mainScreen].scale); /*下面方法, *第一个参数表示区域大小。 *第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。 *第三个参数就是屏幕密度了 */ UIGraphicsBeginImageContextWithOptions(windows.size, YES, scale); CGContextRef context = UIGraphicsGetCurrentContext(); [windows.layer renderInContext:context]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
方法三:webView,scroller截图
/** * 根据视图尺寸获取视图截屏(一屏无法显示完整),适用于UIScrollView UITableviewView UICollectionView UIWebView * * @return UIImage 截取的图片 */ - (UIImage *)scrollViewCutter:(UIScrollView *)scrollView { //保存 CGPoint savedContentOffset = scrollView.contentOffset; CGRect savedFrame = scrollView.frame; scrollView.contentOffset = CGPointZero; scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height); UIImage *image = [self viewCutter:scrollView]; //还原数据 scrollView.contentOffset = savedContentOffset; scrollView.frame = savedFrame; return image; } /** 获取指定的View的屏幕 @return 获取指定View 的截屏结果 */ -(UIImage *)viewCutter:(UIView*)view{ UIGraphicsBeginImageContextWithOptions(view.bounds.size,NO,[[UIScreen mainScreen] scale]); // 方法一 有时导航条无法正常获取 // [self.layer renderInContext:UIGraphicsGetCurrentContext()]; // 方法二 iOS7.0 后推荐使用 [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; UIImage*img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; }
方法四:递归每个windows层的截屏(全屏截图)
如果碰到webViewController 会发现前面两个方法都是无法实现的,那么请看下面方法:
/** * 返回截取到的图片 * * @return UIImage * */ - (UIImage *)imageWithScreenshot { NSData *imageData = [self dataWithScreenshotInPNGFormat]; return [UIImage imageWithData:imageData]; } /** * 截取当前屏幕 * * @return NSData * */ - (NSData *)dataWithScreenshotInPNGFormat { CGSize imageSize = CGSizeZero; UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (UIInterfaceOrientationIsPortrait(orientation)) imageSize = [UIScreen mainScreen].bounds.size; else imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width); UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0); 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); if (orientation == UIInterfaceOrientationLandscapeLeft) { CGContextRotateCTM(context, M_PI_2); CGContextTranslateCTM(context, 0, -imageSize.width); } else if (orientation == UIInterfaceOrientationLandscapeRight) { CGContextRotateCTM(context, -M_PI_2); CGContextTranslateCTM(context, -imageSize.height, 0); } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { CGContextRotateCTM(context, M_PI); CGContextTranslateCTM(context, -imageSize.width, -imageSize.height); } if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES]; } else { [window.layer renderInContext:context]; } CGContextRestoreGState(context); } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return UIImagePNGRepresentation(image); }
综合这四个方案,最终我选择了方案四