需求描述:
有两个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情况下是没法截图的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** 全屏截图方法 @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截图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * 根据视图尺寸获取视图截屏(一屏无法显示完整),适用于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 会发现前面两个方法都是无法实现的,那么请看下面方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** * 返回截取到的图片 * * @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); } |
综合这四个方案,最终我选择了方案四
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步