在iOS中如何将整个UITableView渲染为UIImage?

9

我有一个简单的UITableView,其中包含一些数据。表格的高度大于屏幕大小。现在我需要捕获这个表格的截图(整个表格)。我知道内容后面的单元格会被回收,但也许有一种方法可以捕获它们。不是吗?


请问您能否帮我检查一下附上的问题并提供帮助。我正在尝试将TableView更改为ImageView。 https://stackoverflow.com/questions/70879552/uitableview-to-uiimage-swift。 - Sham Dhiman
14个回答

0

我有同样的需求,需要通过电子邮件将表格视图的图像发送给管理员,希望这可以帮到你。该功能已在Swift 4中实现。

func screenshot() -> UIImage{
    var image = UIImage()

    UIGraphicsBeginImageContextWithOptions(self.tblDetails.contentSize, false, UIScreen.main.scale)

    // save initial values
    let savedContentOffset = self.tblDetails.contentOffset
    let savedFrame = self.tblDetails.frame
    let savedBackgroundColor = self.tblDetails.backgroundColor

    // reset offset to top left point
    self.tblDetails.contentOffset = CGPoint(x: 0, y: 0)
    // set frame to content size
    self.tblDetails.frame = CGRect(x: 0, y: 0, width: self.tblDetails.contentSize.width, height: self.tblDetails.contentSize.height)
    // remove background
    self.tblDetails.backgroundColor = UIColor.clear

    // make temp view with scroll view content size
    // a workaround for issue when image on ipad was drawn incorrectly
    let tempView = UIView(frame: CGRect(x: 0, y: 0, width: self.tblDetails.contentSize.width, height: self.tblDetails.contentSize.height))

    // save superview
    let tempSuperView = self.tblDetails.superview
    // remove scrollView from old superview
    self.tblDetails.removeFromSuperview()
    // and add to tempView
    tempView.addSubview(self.tblDetails)

    // render view
    // drawViewHierarchyInRect not working correctly
    tempView.layer.render(in: UIGraphicsGetCurrentContext()!)
    // and get image
    image = UIGraphicsGetImageFromCurrentImageContext()!

    // and return everything back
    tempView.subviews[0].removeFromSuperview()
    tempSuperView?.addSubview(self.tblDetails)

    // restore saved settings
    self.tblDetails.contentOffset = savedContentOffset
    self.tblDetails.frame = savedFrame
    self.tblDetails.backgroundColor = savedBackgroundColor

    UIGraphicsEndImageContext()

    return image
}

这段代码能够正确地从tableview中渲染图像。然而,tableview本身变成了空白的白色。你有什么想法吗? - Vlad Barash

-1
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height), YES, 0);

CGFloat originY = 0;

CGRect rectFirst =  CGRectMake(0, originY, self.tableView.bounds.size.width, self.view.bounds.size.height);

[self.tableView scrollRectToVisible:rectFirst animated:NO];

[self.tableView drawViewHierarchyInRect:rectFirst afterScreenUpdates:true];

while (originY < self.tableView.contentSize.height) {

   CGRect rectSecond =  CGRectMake(0, originY, self.tableView.bounds.size.width, self.view.bounds.size.height);

    [self.tableView scrollRectToVisible: rectSecond animated:NO];

    [self.tableView drawViewHierarchyInRect: rectSecond afterScreenUpdates:true];

    originY += self.view.bounds.size.height;

}

CGRect rectFinally =  CGRectMake(0, originY, self.tableView.bounds.size.width, self.tableView.contentSize.height - originY);

[self.tableView scrollRectToVisible:rectFinally animated:NO];

[self.tableView drawViewHierarchyInRect:rectFinally afterScreenUpdates:true];

UIImage * image = UIGraphicsGetImageFromCurrentImageContext();  

UIGraphicsEndImageContext();

将animated设置为NO非常重要,不要阻塞UI线程。


-1

如何在Swift 2.2中对UITableView进行快照:

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();
}

创建了很多单元格,截图的布局混乱且只有大约75%的单元格。 - Gargo

-1

UITableView 不会一次性创建所有单元格,但是你可以强制 tableView 加载所有行(不建议这样做)。解决方法是设置 tableView 的高度为 (numRows * heightOfRow),这将使其加载 tableView 所有行。另外,你可以像下面这样将视图转换为图像。

+ (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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接