1

My Swift code for capturing a UITableView as an image isn't working when the table is scrolled down. I essentially have the answer in Objective-C but can't seem to make it work in Swift. Currently this is what I have in Swift:

func snapshotOfCell (inputView: UIView) -> UIView {
    UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
    inputView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext() as UIImage
    UIGraphicsEndImageContext()
    let cellSnapshot : UIView = UIImageView(image: image)
    cellSnapshot.layer.masksToBounds = false

    return cellSnapshot
}

I found this answer but it's in Objective-C:

-(UIImage *) imageWithTableView:(UITableView *)tableView {
    UIView *renderedView = tableView;
    CGPoint tableContentOffset = tableView.contentOffset;
    UIGraphicsBeginImageContextWithOptions(renderedView.bounds.size, renderedView.opaque, 0.0);
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(contextRef, 0, -tableContentOffset.y);
    [tableView.layer renderInContext:contextRef];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

It seems to fix the scroll problem by using a contentOffset. However, I've been trying to integrate it into my Swift function without success. Anyone good with both Objective-C and Swift? Thanks!

Community
  • 1
  • 1
Dave G
  • 12,042
  • 7
  • 57
  • 83

4 Answers4

2

capture whole tableview as a image

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(tableView.contentSize.width, tableView.contentSize.height),false, 0.0)

    let context = UIGraphicsGetCurrentContext()

    let previousFrame = tableView.frame

    tableView.frame = CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.contentSize.width, tableView.contentSize.height);

    tableView.layer.renderInContext(context!)

    tableView.frame = previousFrame

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext();

    imageView.image = image;

capture the screenshot of tableview in a scrolled position

    let contentOffset = tableView.contentOffset

    UIGraphicsBeginImageContextWithOptions(tableView.bounds.size, true, 1)

    let context = UIGraphicsGetCurrentContext()

    CGContextTranslateCTM(context, 0, -contentOffset.y)

    tableView.layer.renderInContext(context!)

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    imageView.image = image;
Jeyamahesan
  • 1,101
  • 7
  • 15
  • Tried this with no luck. It performs like my Swift code. When the table has not been scrolled, it works well, but it doesn't capture the scrolled-table correctly. – Dave G May 06 '16 at 11:06
  • do you want the tabview screenshot after it has been scrolled in some position? – Jeyamahesan May 06 '16 at 12:11
  • Yes, sorry if I didn't make that clear. When I scroll down halfway and then run the code the picture currently appears to capture a lot of white space and isn't correct. I want the picture to reflect what's on screen – Dave G May 06 '16 at 12:14
  • Works great. Thanks very much. – Dave G May 06 '16 at 13:27
2

Swift 3.0 version for capturing entire tableview based on @Jeyamahesan's answer

UIGraphicsBeginImageContextWithOptions(CGSize(width:tableView.contentSize.width, height:tableView.contentSize.height),false, 0.0)
let context = UIGraphicsGetCurrentContext()
let previousFrame = tableView.frame
tableView.frame = CGRect(x: tableView.frame.origin.x, y: tableView.frame.origin.y, width: tableView.contentSize.width, height: tableView.contentSize.height)
tableView.layer.render(in: context!)
tableView.frame = previousFrame
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
Mikrasya
  • 964
  • 12
  • 21
1

Try this piece of code:

-(UIImage *)screenshot {
UIImage *image = nil;

UIGraphicsBeginImageContextWithOptions(tableView.contentSize, false, 0.0);
{
    CGPoint savedContentOffset = tableView.contentOffset;
    CGRect savedFrame = tableView.frame;

    tableView.contentOffset = CGPointMake(0.0, 0.0);
    tableView.frame = CGRectMake(0, 0.0, tableView.contentSize.width, tableView.contentSize.height);

    [tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
    image = UIGraphicsGetImageFromCurrentImageContext();

    tableView.contentOffset = savedContentOffset;
    tableView.frame = savedFrame;
}
UIGraphicsEndImageContext();

return image;
}

Happy Coding..!!

Nirmit Dagly
  • 1,272
  • 1
  • 12
  • 25
  • Thanks, out the door now but will give it a try tonight. Aren't those first two lines in Objective-C? – Dave G May 05 '16 at 11:56
  • Just give a try.. It is tested for scrolling view successfully and I hope it works for you also. The whole code is written in Objective-C. – Nirmit Dagly May 05 '16 at 11:57
0

Please try this one Its may be help to you

- (UIImage*)buildImage:(UIImage*)image
{
   UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);

   [image drawAtPoint:CGPointZero];


   CGFloat scale;

   scale = image.size.width / _workingView.frame.size.width;



       CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale);

   NSLog(@"%f",scale);


   [tableView.layer renderInContext:UIGraphicsGetCurrentContext()];

   UIImage *tmp = UIGraphicsGetImageFromCurrentImageContext();

   UIGraphicsEndImageContext();

   return tmp;
}
Vijay Kachhadiya
  • 366
  • 2
  • 11