Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a whole UITableView as an UIImage in iOS?

I have simple UITableView with some data. The table's height is greater than the screen size. Now I need to catch screenshot of this table (a whole table). I know that cells after the content are dequeued, but maybe there is a way how to capture this. isn't it?

like image 905
Bartłomiej Semańczyk Avatar asked Aug 20 '15 09:08

Bartłomiej Semańczyk


3 Answers

Try this:

 func generateImage(tblview:UITableView) ->UIImage{
        UIGraphicsBeginImageContext(tblview.contentSize);
        tblview.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
        tblview.layer.renderInContext(UIGraphicsGetCurrentContext())
        let row = tblview.numberOfRowsInSection(0)
        let numberofRowsThatShowOnScreen = 4
        var scrollCount = row / numberofRowthatShowinscreen
        
        for var i = 0; i < scrollCount; i++ {
            tblview.scrollToRowAtIndexPath(NSIndexPath(forRow: (i+1) * numberofRowsThatShowOnScreen, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
            tblview.layer.renderInContext(UIGraphicsGetCurrentContext())
        }
        
        let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();
        return image;
}


        
 

and after call method like this.

 var imageView = UIImageView()
     imageView.image = generateImage(tableView)
like image 109
Parth Bhadaja Avatar answered Nov 11 '22 14:11

Parth Bhadaja


Just UITableView's cells to UIImage

UIGraphicsBeginImageContextWithOptions(CGSizeMake(tableView.contentSize.width, tableView.contentSize.height+64+40), true, 0)

for section in 0...tableView.numberOfSections-1 {
    for row in 0...tableView.numberOfRowsInSection(section)-1 {
        let indexPath = NSIndexPath.init(forRow: row, inSection: section)
        let cell = tableView.cellForRowAtIndexPath(indexPath)!

        print("row:\(indexPath.row), frame:\(cell.frame) height:\(cell.frame.height)")

        cell.contentView.drawViewHierarchyInRect(cell.frame, afterScreenUpdates: true)
    }
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
like image 20
Young Hoo Kim Avatar answered Nov 11 '22 14:11

Young Hoo Kim


My solution for Swift 4 !

import Foundation
import UIKit

extension UITableView {

    func asFullImage() -> UIImage? {

        guard self.numberOfSections > 0, self.numberOfRows(inSection: 0) > 0 else {
            return nil
        }

        self.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)

        var height: CGFloat = 0.0
        for section in 0..<self.numberOfSections {
            var cellHeight: CGFloat = 0.0
            for row in 0..<self.numberOfRows(inSection: section) {
                let indexPath = IndexPath(row: row, section: section)
                guard let cell = self.cellForRow(at: indexPath) else { continue }
                cellHeight = cell.frame.size.height
            }
            height += cellHeight * CGFloat(self.numberOfRows(inSection: section))
        }

        UIGraphicsBeginImageContextWithOptions(CGSize(width: self.contentSize.width, height: height), false, UIScreen.main.scale)

        for section in 0..<self.numberOfSections {
            for row in 0..<self.numberOfRows(inSection: section) {
                let indexPath = IndexPath(row: row, section: section)
                guard let cell = self.cellForRow(at: indexPath) else { continue }
                cell.contentView.drawHierarchy(in: cell.frame, afterScreenUpdates: true)

                if row < self.numberOfRows(inSection: section) - 1 {
                    self.scrollToRow(at: IndexPath(row: row+1, section: section), at: .bottom, animated: false)
                }
            }
        }
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }
}

like image 29
David Kieffer Avatar answered Nov 11 '22 12:11

David Kieffer