iOS WebView生成长截图的第三种解决方案

前言

由于项目需要,新近实现了一个长截图库 SnapshotKit。其中,需要支持 UIWebViewWKWebView 组件生成长截图。为了实现这个特性,查阅了很多资料,同时也做了不同的新奇思路尝试,最终实现了一个新的、取巧的技术方案。

以下主要总结了在“WebView生成长截图”需求方面,“网上已有方案”和“我的全新方案”的各自实现要点和优缺点。

WebView生成长截图的已有方案

根据 Google 所搜索到的资料,目前iOS WebView生成长截图的方案主要有2种:

  • 方案一:修改Frame,截图组件
  • 方案二:分页截图组件内容,合成长图

下面将会简述方案一和方案二的具体实现。

方案一:修改Frame,截图组件

方案一的实现要点在于:修改 webView.scrollViewframeSizecontentSize,然后对整个 webView.scrollView 进行截图。

不过,这个方案只适用 UIWebView 组件,因为其是一次性加载网页所有的内容。而 WKWebView 组件,为了节省内存,加载网页内容时,只加载可视部分——这一点类似 UITableView 组件。在修改webView.scrollViewframeSize 后,立即执行了截图操作, 这时候,WKWebView由于还没把网页的内容加载出来,导致生成的长截图是空白的。

方案一核心代码如下:

extension UIScrollView {
   public func takeSnapshotOfFullContent() -> UIImage? {
        let originalFrame = self.frame
        let originalOffset = self.contentOffset

        self.frame = CGRect.init(origin: originalFrame.origin, size: self.contentSize)
        self.contentOffset = .zero

        let backgroundColor = self.backgroundColor ?? UIColor.white

        UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 0)

        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        context.setFillColor(backgroundColor.cgColor)
        context.setStrokeColor(backgroundColor.cgColor)

        self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        self.frame = originalFrame
        self.contentOffset = originalOffset

        return image
    }
}
复制代码

测试代码:

// example code
 private func takeSnapshotOfUIWebView() {
    let image = self.webView.scrollView.takeSnapshotOfFullContent()
   // 处理image
}    
复制代码

方案二:分页截图组件内容,合成长图

方案二的实现要点在于:分页滚动WebView组件的内容,然后生成分页截图,最后把所有分页截图合成一张长图。

这个方案适用于 UIWebView 组件和 WKWebView 组件。

方案二核心代码如下:

你可能感兴趣的:(移动开发)