需求描述:

有两个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);
}

  

综合这四个方案,最终我选择了方案四