How do I capture UIImage of complete contents of UITableView / UIScrollView and make it work on an ios device

4.3k views Asked by At

I am using this wonderfully elegant piece of code Getting a screenshot of a UIScrollView, including offscreen parts to capture the entire contents of a UITableView to be exported to a UIImage.

UIGraphicsBeginImageContextWithOptions(self.controller.tableView.contentSize, YES, 0);
{
    CGPoint savedContentOffset = self.controller.tableView.contentOffset;
    CGRect savedFrame = self.controller.tableView.frame;

    self.controller.tableView.contentOffset = CGPointZero;
    self.controller.tableView.frame = CGRectMake(0, 0, self.controller.tableView.contentSize.width, self.controller.tableView.contentSize.height);

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

    self.controller.tableView.contentOffset = savedContentOffset;
    self.controller.tableView.frame = savedFrame;
}

UIGraphicsEndImageContext();

It works fantastically well in the simulator, however, when I run this code on an iOS device (iphone 4s) i get a whole leap of the following errors when this method is called:

[self.controller.tableView.layer renderInContext: UIGraphicsGetCurrentContext()];

Errors:

Error: CGContextTranslateCTM: invalid context 0x2924b0
Error: CGContextDrawImage: invalid context 0x2924b0
Error: CGContextRestoreGState: invalid context 0x2924b0
Error: CGContextSaveGState: invalid context 0x2924b0
Error: CGContextScaleCTM: invalid context 0x2924b0
Error: CGContextClipToRect: invalid context 0x2924b0
etc...

This code works well when the table views content size is within its bounds but as soon as it is greater than its bounds (even by 1 pixel) it goes into an endless loop of the above errors. But this only happens on the device. Not the simulator.

Any ideas?

1

There are 1 answers

1
Ben Priebe On BEST ANSWER

It turns out that using the [UIImage ..] resizableImageWithCapInsets] method and applying it to the cell backgroundView and adjusting the frame causes all sorts of funky badness to happen on actual devices but not the simulator.

Reverting back to the deprecated [UIImage ..] stretchableImageWithLeftCapWidth: topCapHeight:] method solved it.