如何在 Swift 中截取 UITableView 中选定行的屏幕截图并将其保存为 UIImage?

Posted

技术标签:

【中文标题】如何在 Swift 中截取 UITableView 中选定行的屏幕截图并将其保存为 UIImage?【英文标题】:How can I take a screenshot of selected rows in UITableView in Swift and save it as an UIImage? 【发布时间】:2017-04-15 20:50:02 【问题描述】:

在我的 Swift 应用程序中,我有一个 UITableView,其中包含 4 个静态单元格,然后它具有不同数量的动态单元格。我只想截取静态单元格的屏幕截图。

我找到了以下扩展:

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;
    

来自这个问题How to render a whole UITableView as an UIImage in ios?

但问题是,即使我改变了:

let numberofRowthatShowinscreen = 4

到:

let numberofRowthatShowinscreen = 3

那么它仍然会截取整个UITableView。那么有没有办法将其限制在前 4 行?

【问题讨论】:

你为什么不简单地控制你的表视图数据源数组在调用 captureImage 之前返回yourDataSource.prefix(4) 【参考方案1】:

在您的示例代码中,您将在图像上下文中呈现表格视图的图层。这将始终对整个表视图进行快照。您可以听取评论者的建议并在快照之前调整表格视图的单元格。或者您可以对要渲染的单元格的图层进行快照。例如:

extension UITableView

    func snapshotRows(at indexPaths: Set<IndexPath>) -> UIImage?
    
        guard !indexPaths.isEmpty else  return nil 
        var rect = self.rectForRow(at: indexPaths.first!)
        for indexPath in indexPaths
        
            let cellRect = self.rectForRow(at: indexPath)
            rect = rect.union(cellRect)
        

        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        guard let context = UIGraphicsGetCurrentContext() else  return nil 
        for indexPath in indexPaths
        
            let cell = self.cellForRow(at: indexPath)
            cell?.layer.bounds.origin.y = self.rectForRow(at: indexPath).origin.y - rect.minY
            cell?.layer.render(in: context)
            cell?.layer.bounds.origin.y = 0
        

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    

用法:

let image = tableView.snapshotRows(at: Set([IndexPath(row: 0, section: 0), IndexPath(row: 0, section: 1)]))

只会对特定单元格进行快照。正如另一篇文章的答案所说,这仅适用于重复使用单元格的可见单元格。

【讨论】:

此方法在 iOS 13 中不适用于动态高度单元格。

以上是关于如何在 Swift 中截取 UITableView 中选定行的屏幕截图并将其保存为 UIImage?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式截取可扩展的uitableview的屏幕截图

如何在 Swift 中截取全屏截图?

如何在 swift 中增加 ScrollView 中的 UITableView 高度

Swift:如何在 UITableView 中定位标记的 UITextView?

如何使用 Swift3 在​​第二个 UITableView 中获取第一个 UITableView 的索引 path.row

如何在 swift iOS 中的 UIAlertcontroller 中显示 UITableview?