WKWebView takeSnapshot没有滚动条macOS

问题描述

尝试使用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)
    }
}