当前位置: 动力学知识库 > 问答 > 编程问答 >

swift - 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?

网友答案:

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 numberofRowthatShowinscreen = 4
        var scrollCount = row / numberofRowthatShowinscreen

        for var i=0;i < scrollCount ; i++ {
            tblview.scrollToRowAtIndexPath(NSIndexPath(forRow: (i+1)*numberofRowthatShowinscreen, 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)
网友答案:

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)!
        let height = cell.frame.height

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

        cell.contentView.drawViewHierarchyInRect(cell.frame, afterScreenUpdates: true)
    }
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
网友答案:

Tranfered Parth Bhadaja's answer to Swift 3 and as extension with computed property:

extension UITableView {
    var capturedImage : UIImage {
        UIGraphicsBeginImageContext(contentSize);
        scrollToRow(at: NSIndexPath(row: 0, section: 0) as IndexPath, at:     UITableViewScrollPosition.top, animated: false)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let row = numberOfRows(inSection: 0)
        let numberofRowthatShowinscreen = 4
        let scrollCount = row / numberofRowthatShowinscreen

        for i in 0 ..< scrollCount  {
            scrollToRow(at: NSIndexPath(row: (i+1)*numberofRowthatShowinscreen, section: 0) as     IndexPath, at: UITableViewScrollPosition.top, animated: false)
            layer.render(in: UIGraphicsGetCurrentContext()!)
        }

        let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext();
        return image;
    }
}

Usage:

let image = tableView.capturedImage
网友答案:

To take a screenshot of an UIView you can use the following:

UIGraphicsBeginImageContext(tableview.frame.size)
tableview.layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext() 

This will work for whatever is visible, and may work for any already loaded but off-screen views.
In an UITableView, only the visible cells plus 1 off-screen cell at each end of the table are loaded. The other ones do not actually exist... yet. So you can't "capture" them.

网友答案:

You can create graphics context with the size of tableView.contentSize. After that you have to run loop threw all indexPaths and draw each cell. You can have one cell which will be reused for drawing cells which are out of screen - just change content of that with required data and draw it.

网友答案:

For snapshot in of uitableview with swift 2.2:

func printScreen(){
    UIGraphicsBeginImageContextWithOptions(Table_LigaParcial.contentSize, false, UIScreen.mainScreen().scale)
    Table_LigaParcial.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
    Table_LigaParcial.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let row = Table_LigaParcial.numberOfRowsInSection(0)
    let numberofRowthatShowinscreen = 4
    var scrollCount = row / numberofRowthatShowinscreen

    for var i=0;i < scrollCount ; i+=1 {
        Table_LigaParcial.scrollToRowAtIndexPath(NSIndexPath(forRow: (i)*numberofRowthatShowinscreen, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
        Table_LigaParcial.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    }

    let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext();
}
网友答案:

UItableView by don't create all cells at a time, but you can force tableView to load all (which is not recommended) work around is just set the height of tableView ( numRows * heightOfRow) and this will make it load tableView all rows. And you can convert view to image like below

+ (UIImage*)imageFromView:(UIView *)view{
       UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [UIScreen mainScreen].scale);
    [view drawViewHierarchyInRect:CGRectMake(0, 0, view.bounds.size.width, view.bounds.size.height) afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
网友答案:

add render method to UITableView through category

- (UIImage *)render {

    //save the origin infos for later to restore
    CGPoint originContentOffset = self.contentOffset;

    //force jump to table view's top
    self.contentOffset = CGPointZero;

    UIGraphicsBeginImageContext(self.contentSize);

    CGContextRef *ctx = UIGraphicsGetCurrentContext();

    //render header 
    [self.tableHeaderView.layer renderInContext:ctx];

    //render sections
    NSInteger numberOfSections = [self numberOfSections];
    for (int section = 0; section < numberOfSections; section++) {
        NSInteger numberOfRows = [self numberOfRowsInSection:section];
        for (int row = 0; row < numberOfRows; row++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
            //check cell is visible
            if ([self cellForRowAtIndexPath:indexPath]) {
                [self scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:false];
                [self.layer renderInContext:ctx];
            }
        }
    }

    //render footer
    [self.tableFooterView.layer renderInContext:ctx];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //restore infos
    self.contentOffset = originContentOffset;

    return image;
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: