问题描述
尝试使用WKWebView
渲染SVG文件。但是,滚动条显示在结果快照中。
根据
WebKit implementation有私有方法_setMinimumLayoutWidth:
,它将禁用文档的滚动性。该解决方案有效,但这是私有方法。
寻找一种无需滚动条即可拍摄快照的方法
PS:旧的WebView不会出现此问题,因为我可以轻松地修改scrollView。 10.16具有createPDF,背景和滚动条都没有问题
override init() {
webView = WKWebView(frame: .zero)
//webView.setValue(false,forKey: "alwaysShowsverticalScroller") //doesn't work + private
//webView.setValue(false,forKey: "alwaysShowsHorizontalScroller") //doesn't work + private
//webView.perform(selector,with: NSNumber(value: 500.0))
webView.setValue(500.0,forKey: "minimumLayoutWidth") //works but private
webView.setValue(false,forKey: "draws" + "background".capitalized) //works but private
super.init()
webView.navigationDelegate = self
}
func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
//...some code to resize
webView.setFrameSize(NSMakeSize(svgNodeWidth * zoomFactor + offset,svgNodeHeight * zoomFactor + offset))
let configuration = WKSnapshotConfiguration()
webView.takeSnapshot(with: configuration) { (image,error) in
//resulting image will show empty area for horizontal and vertical scrollbar
if let error = error {
debugPrint(error)
}
self.completion?(image)
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="10" height="10" fill="purple" xmlns="http://www.w3.org/2000/svg">
<!-- With a width of 0 or less,nothing will be rendered -->
<rect x="0" y="0" width="10" height="10" fill="purple"/>
</svg>
解决方法
问题只出现在 macOS ~10.15.3 上。它不存在于 10.13/10.14/11.0。额外的填充将解决这个问题。
let padding : CGFloat = 50
func adjustSizeAndMagnify() {
if svgNodeWidth > 0 && svgNodeHeight > 0 {
zoomFactor = [minimumWidth / svgNodeWidth,minimumHeight / svgNodeHeight].max() ?? 1
let backingScale = NSScreen.main?.backingScaleFactor ?? 1
zoomFactor = zoomFactor / backingScale
webView.setFrameSize(NSMakeSize(svgNodeWidth * zoomFactor + padding,svgNodeHeight * zoomFactor + padding))
webView.magnification = zoomFactor
}
}
func takeSnapshot() {
adjustSizeAndMagnify()
let configuration = WKSnapshotConfiguration()
configuration.rect = NSMakeRect(0,webView.frame.size.width - padding,webView.frame.size.height - padding)
webView.takeSnapshot(with: configuration) { (image,error) in
if let error = error {
debugPrint(error)
}
self.completion?(image)
}
}