我可以通过调整UIWebView
UIScrollView
的框架来捕获UIWebView
的所有内容屏幕截图。但是,我无法通过相同的方法捕获WKWebView
的所有内容屏幕截图。
我用于捕获UIWebView
的方法如下:
webview.scrollView
webview.scrollView
的超级视图webview.scrollView
。框架与webview.scrollView.contentSize
renderInContext
或drawViewHierarchyInRect
但是,此方法将捕获WKWebview
的白色屏幕截图。它没有用!
我打印了WKWebView
的所有级别,然后我发现UIView
(WKContentView)的大小与contentView相同,您可以在此级别找到此视图:
我也尝试按WKContentView
捕获,然后我发现只能抓取可见的视图。
无论如何,任何人都可以告诉我如何捕获WKWebView
的完整页面内容屏幕截图?
答案 0 :(得分:5)
请参阅此answer
iOS 11.0及更高版本,Apple提供了以下API来捕获WKWebView的快照。
@available(iOS 11.0, *)
open func takeSnapshot(with snapshotConfiguration: WKSnapshotConfiguration?, completionHandler: @escaping (UIImage?, Error?) -> Swift.Void)
答案 1 :(得分:3)
Swift 3,Xcode 8
func takeScreenshot() -> UIImage? {
let currentSize = webView.frame.size
let currentOffset = webView.scrollView.contentOffset
webView.frame.size = webView.scrollView.contentSize
webView.scrollView.setContentOffset(CGPoint.zero, animated: false)
let rect = CGRect(x: 0, y: 0, width: webView.bounds.size.width, height: webView.bounds.size.height)
UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
webView.drawHierarchy(in: rect, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
webView.frame.size = currentSize
webView.scrollView.setContentOffset(currentOffset, animated: false)
return image
}
答案 2 :(得分:1)
-xcode 10和swift 4.2-
使用它;
//这是获取屏幕截图的按钮
@IBAction func snapShot(_ sender: Any) {
captureScreenshot()
}
//这是处理屏幕截图功能的功能。
func captureScreenshot(){
let layer = UIApplication.shared.keyWindow!.layer
let scale = UIScreen.main.scale
// Creates UIImage of same size as view
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// THIS IS TO SAVE SCREENSHOT TO PHOTOS
UIImageWriteToSavedPhotosAlbum(screenshot!, nil, nil, nil)
}
,您必须将这些密钥添加到info.plist;
key value = "Privacy - Photo Library Additions Usage Description" ,
key value = Privacy - Photo Library Usage Description
答案 3 :(得分:0)
Swift 3,Xcode 9: 我创建了一个扩展来实现这一目标。希望这会对你有所帮助。
class MasterViewController: UIViewController {
var masters = [Master]()
override func viewDidLoad() {
super.viewDidLoad()
// add array with 10 players with hp points
masters.append(Master(playerName: "John Doe", hp: 100, avatar: nil))
masters.append(Master(playerName: "Jack Jones", hp: 50, avatar: nil))
masters.append(Master(playerName: "Susan Scott", hp: 150, avatar: nil))
// Add any masters here ...
// Another way of doing it : (0..<10).forEach { masters.append(Master(playerName: ""+$0, hp: 12 + $0, avatar: nil)) }
// filter array to return alive players
let aliveMasters = masters.filter { $0.isAlive }
// map the resulenter code hereting array and display this table as a list.
// Here aliveMasters is already an array of Masters, map is used to "transform" data
let mappedMasters: [String] = masters.map { $0.playerName }
print("Alive Masters are : \(mappedMasters)")
}
}
答案 4 :(得分:0)
这是一个 iOS 11+ 示例,用于对 WKWebView 进行快照无需任何延迟来呈现内容。
关键是确保您不会收到空白快照。最初,我们遇到了输出图像为空白的问题,并且必须引入延迟才能在输出图像中包含 Web 内容。我在许多帖子中看到了延迟的解决方案,我建议不要使用它,因为它是一个不必要的不可靠和性能不佳的解决方案。对我们来说重要的解决方案是设置 rect
的 WKSnapshotConfiguration
并使用 JavaScript 函数等待渲染并接收正确的宽度和高度。
设置 WKWebView:
// Important: You can set a width here which will also be reflected in the width of the snapshot later
let webView = WKWebView(frame: .zero)
webView.configuration.dataDetectorTypes = []
webView.navigationDelegate = self
webView.scrollView.contentInsetAdjustmentBehavior = .never
webView.loadHTMLString(htmlString, baseURL: Bundle.main.resourceURL)
捕获快照:
func webView(
_ webView: WKWebView,
didFinish navigation: WKNavigation!
) {
// Wait for the page to be rendered completely and get the final size from javascript
webView.evaluateJavaScript("document.readyState", completionHandler: { [weak self] (readyState, readyStateError) in
webView.evaluateJavaScript("document.documentElement.scrollWidth", completionHandler: {(contentWidth, widthError) in
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (contentHeight, heightError) in
guard readyState != nil,
let contentHeight = contentHeight as? CGFloat,
let contentWidth = contentWidth as? CGFloat else {
[Potential error handling...]
return
}
let rect = CGRect(
x: 0,
y: 0,
width: contentWidth,
height: contentHeight
)
let configuration = WKSnapshotConfiguration()
configuration.rect = rect
if #available(iOS 13.0, *) {
configuration.afterScreenUpdates = true
}
webView.takeSnapshot(with: configuration) { (snapshotImage, error) in
guard let snapshotImage = snapshotImage else {
[Potential error handling...]
}
[Do something with the image]
}
})
})
})
}
答案 5 :(得分:-2)
更新:不确定为什么Jason会在整个网络上坚持这个答案。它没有解决如何截取整个WKWebView内容的问题......包括屏幕外的内容。
试试这个:
func snapshot() -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.webView.bounds.size, true, 0);
self.webView.drawViewHierarchyInRect(self.webView.bounds, afterScreenUpdates: true);
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(snapshotImage, nil, nil, nil)
return snapshotImage
}
图像将自动保存到iOS相机胶卷(通过UIImageWriteToSavedPhotosAlbum())。