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

后端 未结 13 2140
太阳男子
太阳男子 2020-12-17 23:54

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 k

相关标签:
13条回答
  • 2020-12-18 00:30

    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;
    }
    
    0 讨论(0)
  • 2020-12-18 00:32

    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();
    }
    
    0 讨论(0)
  • 2020-12-18 00:34

    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.

    0 讨论(0)
  • 2020-12-18 00:34

    Swift 4 version of Parth Bhadaja's answer:

    func generateImage(tableView:UITableView) -> UIImage {
        UIGraphicsBeginImageContext(tableView.contentSize);
        tableView.scrollToRow(at: NSIndexPath(row: 0, section: 0) as IndexPath, at: UITableViewScrollPosition.top, animated: false)
        tableView.layer.render(in: UIGraphicsGetCurrentContext()!)
        let row = tableView.numberOfRows(inSection: 0)
        let numberofRowthatShowinscreen = 4
        let scrollCount = row / numberofRowthatShowinscreen
    
        for i in 0..<scrollCount {
            tableView.scrollToRow(at: NSIndexPath(row: (i+1)*numberofRowthatShowinscreen, section: 0) as IndexPath, at: UITableViewScrollPosition.top, animated: false)
            tableView.layer.render(in: UIGraphicsGetCurrentContext()!)
        }
    
        let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext();
        return image;
    }
    

    Should be noted that this function does return an image of the whole tableView, even cells which haven't been loaded onto the screen yet.

    0 讨论(0)
  • 2020-12-18 00:37

    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;
    }
    
    0 讨论(0)
  • 2020-12-18 00:37

    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
    
    0 讨论(0)
提交回复
热议问题